home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-22 | 101.4 KB | 2,817 lines |
- Implementation Notes for CLISP
- ==============================
- Last modified: 21 July 1996.
-
- This implementation is mostly compatible to the standard reference
-
- Guy L. Steele Jr.: Common Lisp - The Language (1st ed.).
- Digital Press 1984, 465 pages.
- ("CLtL1" for short)
-
- and to the older parts of
-
- Guy L. Steele Jr.: Common Lisp - The Language (2nd ed.).
- Digital Press 1990, 1032 pages.
- ("CLtL2" for short)
-
-
- These notes document the differences of the CLISP implementation of Common
- Lisp to the standard CLtL1, and some implementation details.
-
- The differences between CLtL1 and CLtL2 are made up of X3J13 votes. CLISP's
- position with respect to these votes is listed in cltl2.txt.
-
-
- CHAPTER 1: Introduction
- -----------------------
-
- No notes.
-
-
- CHAPTER 2: Data Types
- ---------------------
-
- All the data types are implemented: numbers, characters, symbols, lists,
- arrays, hash tables, readtables, packages, pathnames, streams, random
- states, structures and functions.
-
- 2.1.3.
- ------
-
- There are four floating point types: short-float, single-float, double-float
- and long-float:
- sign mantissa exponent
- short-float 1 bit 16+1 bits 8 bits
- single-float 1 bit 23+1 bits 8 bits CLISP uses IEEE format
- double-float 1 bit 52+1 bits 11 bits CLISP uses IEEE format
- long-float 1 bit >=64 bits 32 bits
-
- The single and double float formats are those of the IEEE standard (1981),
- except that CLISP does not support features like +0, -0, +inf, -inf, gradual
- underflow, NaN, etc. (Common Lisp does not make use of these features.)
-
- Long floats have variable mantissa length, which is a multiple of 16 (or 32,
- depending on the word size of the processor). The default length used when
- long floats are read is given by the place (LONG-FLOAT-DIGITS). It can be
- set by (SETF (LONG-FLOAT-DIGITS) nnn), where nnn is a positive integer.
-
- 2.1.4.
- ------
-
- Complex numbers can have a real part and an imaginary part of different
- types. For example, (SQRT -9.0) evaluates to the number #C(0 3.0), which has
- a real part of exactly 0, not only 0.0 (which would mean "approximately 0").
- The type specifier for this is (COMPLEX INTEGER SINGLE-FLOAT), and
-
- (COMPLEX type-of-real-part type-of-imaginary-part)
-
- in general.
- The type specifier (COMPLEX type) is equivalent to (COMPLEX type type).
-
- 2.2.1.
- ------
-
- The characters are ordered according to the ASCII encoding.
-
- More precisely, CLISP uses the ISO Latin-1 (ISO 8859-1) character set:
- $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F
- $00 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
- $10 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
- $20 ! " # $ % & ' ( ) * + , - . /
- $30 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
- $40 @ A B C D E F G H I J K L M N O
- $50 P Q R S T U V W X Y Z [ \ ] ^ _
- $60 ` a b c d e f g h i j k l m n o
- $70 p q r s t u v w x y z { | } ~
- $80
- $90
- $A0 á í ó ú ñ Ñ ª º ¿ ⌐ ¬ ½ ¼ ¡ « »
- $B0 ░ ▒ ▓ │ ┤ ╡ ╢ ╖ ╕ ╣ ║ ╗ ╝ ╜ ╛ ┐
- $C0 └ ┴ ┬ ├ ─ ┼ ╞ ╟ ╚ ╔ ╩ ╦ ╠ ═ ╬ ╧
- $D0 ╨ ╤ ╥ ╙ ╘ ╒ ╓ ╫ ╪ ┘ ┌ █ ▄ ▌ ▐ ▀
- $E0 α ß Γ π Σ σ µ τ Φ Θ Ω δ ∞ φ ε ∩
- $F0 ≡ ± ≥ ≤ ⌠ ⌡ ÷ ≈ ° ∙ · √ ⁿ ² ■
- Here ** are control characters, not graphic characters. (The characters left
- blank here cannot be represented in this character set).
-
- The following are standard characters:
- #\Space $20
- #\Newline $0A
- The following are semi-standard characters:
- #\Backspace $08
- #\Tab $09
- #\Linefeed $0A
- #\Page $0C
- #\Return $0D
- #\Rubout $7F
-
- 2.2.2.
- ------
-
- #\Newline is the delimiter between lines.
-
- When reading from a file, CR/LF is converted to #\Newline, and CR not
- followed by LF is read as #\Return.
-
- 2.2.3.
- ------
-
- There are the following additional characters with names:
- #\Null $00
- #\Bell $07
- #\Escape $1B
-
- 2.2.4.
- ------
-
- The code of a character is >=0, <256. CHAR-CODE-LIMIT = 256.
-
- There are fonts 0 to 15, and CHAR-FONT-LIMIT = 16. But the system itself
- uses only font 0.
-
- The following bits attributes are implemented: :CONTROL, :META, :SUPER,
- :HYPER. Therefore CHAR-BITS-LIMIT = 16.
- The system itself uses these bits only to mention special keys and
- Control/Alternate/Shift key status on return from
- (READ-CHAR *KEYBOARD-INPUT*).
-
- 2.5.
- ----
-
- The maximum rank (number of dimensions) of an array is 65535 on 16-bit
- processors, 4294967295 on 32-bit processors.
-
- 2.10.
- -----
-
- The CLtL2 types BROADCAST-STREAM, CONCATENATED-STREAM, ECHO-STREAM,
- SYNONYM-STREAM, STRING-STREAM, FILE-STREAM, TWO-WAY-STREAM are implemented.
-
- 2.13.
- -----
-
- All the functions built by FUNCTION, COMPILE and the like are atoms. There
- are built-in functions written in C, compiled functions (both of type
- COMPILED-FUNCTION) and interpreted functions (of type FUNCTION).
- The possible function names (CLtL1 p. 59) are symbols and lambda expressions.
-
- 2.14.
- -----
-
- This is the list of objects whose external representation can not be
- meaningfully read in:
- * all structures lacking a keyword constructor.
- * all arrays except strings, if *PRINT-ARRAY* = NIL.
- * #<SYSTEM-FUNCTION name> built-in function written in C
- * #<ADD-ON-SYSTEM-FUNCTION name> other function written in C
- * #<SPECIAL-FORM name> special form handler
- * #<COMPILED-CLOSURE name> compiled function, if *PRINT-CLOSURE* = NIL
- * #<CLOSURE name ...> interpreted function
- * #<FRAME-POINTER #x...> pointer to a stack frame
- * #<DISABLED POINTER> frame pointer which has become invalid on
- exit from the corresponding BLOCK or TAGBODY
- * #<...-STREAM ...> stream
- * #<PACKAGE name> package
- * #<HASH-TABLE #x...> hash table, if *PRINT-ARRAY* = NIL
- * #<READTABLE #x...> readtable
- * #<SYMBOL-MACRO form> symbol-macro handler
- * #<FOREIGN-POINTER #x...> foreign pointer
- * #<FOREIGN-ADDRESS #x...> foreign address
- * #<FOREIGN-VARIABLE name #x...> foreign variable
- * #<FOREIGN-FUNCTION name #x...> foreign function
- * #<UNBOUND> "value" of a symbol without value, "value"
- of an unsupplied optional or keyword argument
- * #<SPECIAL REFERENCE> environment marker for variables declared
- SPECIAL
- * #<DOT> internal READ result for "."
- * #<END OF FILE> internal READ result, when the end of file
- is reached
- * #<READ-LABEL ...> intermediate READ result for #n#
- * #<ADDRESS #x...> machine address, should not occur
- * #<SYSTEM-POINTER #x...> should not occur
-
- 2.15.
- -----
-
- The type NUMBER is the disjoint union of the types REAL and COMPLEX. (CLtL
- wording: "exhaustive partition")
- The type REAL is the disjoint union of the types RATIONAL and FLOAT.
- The type RATIONAL is the disjoint union of the types INTEGER and RATIO.
- The type INTEGER is the disjoint union of the types FIXNUM and BIGNUM.
- The type FLOAT is the disjoint union of the types SHORT-FLOAT, SINGLE-FLOAT,
- DOUBLE-FLOAT and LONG-FLOAT.
-
-
- CHAPTER 3: Scope and Extent
- ---------------------------
-
- is implemented as described.
-
-
- CHAPTER 4: Type Specifiers
- --------------------------
-
- 4.4.
- ----
-
- The CLtL2 type specifier (EQL object) denotes the singleton set {object}.
-
- 4.5.
- ----
-
- The general form of the COMPLEX type specifier is
- (COMPLEX type-of-real-part type-of-imaginary-part).
- The type specifier (COMPLEX type) is equivalent to (COMPLEX type type).
-
- 4.6.
- ----
-
- The CLtL2 type specifier (REAL low high) denotes the real numbers between low
- and high.
-
- 4.7.
- ----
-
- DEFTYPE lambda lists are subject to destructuring (nested lambda lists are
- allowed, as in DEFMACRO) and may contain a &WHOLE marker, but no
- &ENVIRONMENT marker.
-
- 4.9.
- ----
-
- The possible results of TYPE-OF are:
- CONS
- SYMBOL NULL
- FIXNUM BIGNUM RATIO SHORT-FLOAT SINGLE-FLOAT DOUBLE-FLOAT LONG-FLOAT COMPLEX
- CHARACTER
- (ARRAY element-type dimensions), (SIMPLE-ARRAY element-type dimensions)
- (VECTOR T size), (SIMPLE-VECTOR size)
- (STRING size), (SIMPLE-STRING size)
- (BIT-VECTOR size), (SIMPLE-BIT-VECTOR size)
- FUNCTION COMPILED-FUNCTION
- STREAM FILE-STREAM SYNONYM-STREAM BROADCAST-STREAM CONCATENATED-STREAM
- TWO-WAY-STREAM ECHO-STREAM STRING-STREAM
- PACKAGE HASH-TABLE READTABLE PATHNAME LOGICAL-PATHNAME RANDOM-STATE BYTE
- LOAD-TIME-EVAL SYMBOL-MACRO FOREIGN-VARIABLE FOREIGN-FUNCTION READ-LABEL
- FRAME-POINTER SYSTEM-INTERNAL
- ADDRESS (should not occur)
- any other symbol (structure types or CLOS classes)
- a class (CLOS classes without proper name)
-
-
- CHAPTER 5: Program Structure
- ----------------------------
-
- 5.1.3.
- ------
-
- In addition to the 24 special forms listed on p. 57 (CLtL2: p. 73), the
- CLtL2 special forms LOCALLY, SYMBOL-MACROLET, LOAD-TIME-VALUE are implemented,
- and the macros
- PSETQ, PROG1, PROG2, WHEN, UNLESS, COND, MULTIPLE-VALUE-LIST,
- MULTIPLE-VALUE-BIND, MULTIPLE-VALUE-SETQ, AND, OR
- are implemented as special forms.
-
- Constants may not be bound dynamically or lexically.
-
- 5.2.2.
- ------
-
- LAMBDA-LIST-KEYWORDS =
- (&OPTIONAL &REST &KEY &ALLOW-OTHER-KEYS &AUX &BODY &WHOLE &ENVIRONMENT)
-
- LAMBDA-PARAMETERS-LIMIT is 65536 on 16-bit processors, 4294967296 on 32-bit
- processors.
-
- 5.3.
- ----
-
- DEFUN and DEFMACRO are allowed in non-toplevel positions.
- As an example, consider the old (CLtL1) definition of GENSYM:
- (let ((gensym-prefix "G")
- (gensym-count 1))
- (defun gensym (&optional (x nil s))
- (when s
- (cond ((stringp x) (setq gensym-prefix x))
- ((integerp x)
- (if (minusp x)
- (error "~S: index ~S is negative" 'gensym x)
- (setq gensym-count x)
- ))
- (t (error "~S: argument ~S of wrong type" 'gensym x))
- ) )
- (prog1
- (make-symbol
- (concatenate 'string
- gensym-prefix
- (write-to-string gensym-count :base 10 :radix nil)
- ) )
- (incf gensym-count)
- ) )
-
- 5.3.2.
- ------
-
- (PROCLAIM '(SPECIAL var)) declarations may not be undone. The same holds
- for DEFVAR, DEFPARAMETER and DEFCONSTANT declarations.
-
- It is an error if a DEFCONSTANT variable is bound at the moment the
- DEFCONSTANT is executed, but DEFCONSTANT does not check this.
-
- Constants may not be bound dynamically or lexically.
-
- 5.3.3.
- ------
-
- EVAL-WHEN also accepts the situations (NOT EVAL) and (NOT COMPILE).
-
-
- CHAPTER 6: Predicates
- ---------------------
-
- 6.2.2.
- ------
-
- REALP returns T is its argument is a real number, NIL otherwise.
-
- COMPILED-FUNCTION-P returns T on built-in functions written in C, compiled
- functions and special form handlers. Therefore COMPILED-FUNCTION is not a
- subtype of FUNCTION.
-
- 6.3.
- ----
-
- EQ compares characters and fixnums as EQL does. No unnecessary copies are
- made of characters and numbers. Nevertheless, one should use EQL.
-
- (let ((x y)) (eq x x)) always returns T, regardless of y.
-
- 6.4.
- ----
-
- AND and OR are implemented as special forms and, as such, rather efficient.
-
-
- CHAPTER 7: Control Structure
- ----------------------------
-
- 7.1.1.
- ------
-
- (FUNCTION symbol) returns the local function definition established by FLET
- or LABELS, if it exists, otherwise the global function definition.
-
- The CLtL2 place (FDEFINITION function-name) is implemented.
-
- (SPECIAL-FORM-P symbol) returns NIL or T. If it returns T, then
- (SYMBOL-FUNCTION symbol) returns the (useless) special form handler.
-
- 7.1.2.
- ------
-
- PSETQ is implemented as a special form and, as such, rather efficient.
-
- 7.2.
- ----
-
- (SETF (SYMBOL-FUNCTION symbol) object) requires object to be either a
- function, a SYMBOL-FUNCTION return value or a lambda expression. A lambda
- expression is thereby immediately converted to a function.
-
- SETF also accepts places yielding multiple values.
-
- Additional places:
-
- * FUNCALL:
- (SETF (FUNCALL #'symbol ...) object) and
- (SETF (FUNCALL 'symbol ...) object)
- are equivalent to (SETF (symbol ...) object).
-
- * GET-DISPATCH-MACRO-CHARACTER:
- (SETF (GET-DISPATCH-MACRO-CHARACTER ...) ...)
- performs a SET-DISPATCH-MACRO-CHARACTER.
-
- * LONG-FLOAT-DIGITS:
- (SETF (LONG-FLOAT-DIGITS) digits) sets the default mantissa length of long
- floats to digits bits.
-
- * VALUES:
- (SETF (VALUES place1 ... placek) form)
- is approximately equivalent to
- (MULTIPLE-VALUE-BIND (dummy1 ... dummyk) form
- (SETF place1 dummy1 ... placek dummyk)
- (VALUES dummy1 ... dummyk)
- )
- Example:
- (SETF (VALUES A B) (VALUES B A)) interchanges the values of A and B.
-
- * VALUES-LIST:
- (SETF (VALUES-LIST list) form) is equivalent to
- (VALUES-LIST (SETF list (MULTIPLE-VALUE-LIST form)))
-
- &KEY markers in DEFSETF lambda lists are supported, but the corresponding
- keywords must appear literally in the program text.
-
- (GET-SETF-METHOD form &optional env) and
- (GET-SETF-METHOD-MULTIPLE-VALUE form &optional env)
- receives as optional argument the environment necessary for macro expansions.
- In DEFINE-SETF-METHOD lambda lists, one can specify &ENVIRONMENT and a
- variable, which will be bound to the environment. This environment should be
- passed to all calls of GET-SETF-METHOD and GET-SETF-METHOD-MULTIPLE-VALUE.
- If this is done, even local macros will be interpreted as places correctly.
-
- 7.3.
- ----
-
- CALL-ARGUMENTS-LIMIT is 65536 on 16-bit processors, 4294967296 on 32-bit
- processors.
-
- 7.4.
- ----
-
- PROG1 and PROG2 are implemented as special forms and, as such, rather
- efficient.
-
- 7.5.
- ----
-
- The CLtL2 special form SYMBOL-MACROLET is implemented.
-
- The macro DEFINE-SYMBOL-MACRO establishes symbol macros with global scope
- (as opposed to symbol macros defined with SYMBOL-MACROLET, which have local
- scope): (DEFINE-SYMBOL-MACRO symbol expansion).
- The function SYMBOL-MACRO-EXPAND tests for a symbol macro: If symbol is
- defined as symbol macro, (SYMBOL-MACRO-EXPAND symbol) returns two values,
- T and the expansion, else it returns NIL.
- Calling BOUNDP on a symbol defined as symbol macro returns T.
- Calling SYMBOL-VALUE on a symbol defined as symbol macro returns the value
- of the expansion. Calling SET on a symbol defined as symbol macro calls
- SETF on the expansion.
- Calling MAKUNBOUND on a symbol defined as symbol macro removes the symbol
- macro definition.
-
- If using the optional package MACROS3:
- The macros LETF and LETF* are like LET and LET*, resp., except that they
- can bind places, even places with multiple values.
- Example:
- (LETF (((VALUES A B) form)) ...)
- is equivalent to
- (MULTIPLE-VALUE-BIND (A B) form ...)
- (LETF (((FIRST L) 7)) ...)
- is approximately equivalent to
- (LET* ((#:G1 L) (#:G2 (FIRST #:G1)))
- (UNWIND-PROTECT (PROGN (SETF (FIRST #:G1) 7) ...)
- (SETF (FIRST #:G1) #:G2)
- ) )
-
- 7.6.
- ----
-
- WHEN, UNLESS, COND are implemented as special forms and, as such, rather
- efficient.
-
- 7.8.4.
- ------
-
- The function MAPCAP is like MAPCAN, except that it concatenates the
- resulting lists with APPEND instead of NCONC:
- (MAPCAP fun x1 ... xn) == (apply #'append (mapcar fun x1 ... xn))
- (Actually a bit more efficient that this would be.)
-
- The function MAPLAP is like MAPCON, except that it concatenates the
- resulting lists with APPEND instead of NCONC:
- (MAPLAP fun x1 ... xn) = (apply #'append (maplist fun x1 ... xn))
- (Actually a bit more efficient that this would be.)
-
- 7.9.1.
- ------
-
- MULTIPLE-VALUES-LIMIT = 128
-
- MULTIPLE-VALUE-LIST, MULTIPLE-VALUE-BIND, MULTIPLE-VALUE-SETQ are
- implemented as special forms and, as such, rather efficient.
-
- The macro NTH-VALUE:
- (NTH-VALUE n form) returns the (n+1)st value (n>=0) of form.
-
-
- CHAPTER 8: Macros
- -----------------
-
- 8.3.
- ----
-
- The CLtL2 macro DESTRUCTURING-BIND is implemented. It does not perform full
- error checking.
-
-
- CHAPTER 9: Declarations
- -----------------------
-
- 9.1.
- ----
-
- The CLtL2 macro DECLAIM is implemented.
-
- 9.2.
- ----
-
- The declarations (TYPE type var ...), (FTYPE type fun ...),
- (FUNCTION name arglist result-type), (OPTIMIZE (quality value) ...)
- are ignored by the interpreter and the compiler.
-
- The CLtL2 declaration (OPTIMIZE (DEBUG ...)) is legal.
-
- Additional declarations:
-
- * The dpANS declaration (IGNORABLE var ...) affects the variable binding for
- the variable var. The compiler will not warn about the variable, regardless
- whether it is used or not.
-
- * The declaration (COMPILE) has the effect that the current form is compiled
- prior to execution.
- Examples:
- (LOCALLY (DECLARE (COMPILE)) form)
- executes a compiled version of form.
- (let ((x 0))
- (flet ((inc () (declare (compile)) (incf x))
- (dec () (decf x)))
- (values #'inc #'dec)
- ) )
- returns two functions. The first is compiled and increments x, the second
- is interpreted (slower) and decrements the same x.
-
- 9.3.
- ----
-
- The type assertion (THE value-type form) enforces a type check in
- interpreted code. No type check is done in compiled code.
-
- If using the optional package MACROS3:
- (ETHE value-type form) enforces a type check in both interpreted and
- compiled code.
-
-
- CHAPTER 10: Symbols
- -------------------
-
- No notes.
-
-
- CHAPTER 11: Packages
- --------------------
-
- 11.6.
- -----
-
- The package SYSTEM has the nicknames "SYS" and, additionally, "COMPILER".
-
- The CLtL2 packages
- * COMMON-LISP with nickname "CL" and
- * COMMON-LISP-USER with nickname "CL-USER"
- are implemented. The package COMMON-LISP exports only those symbols
- from the proposed ANSI CL draft that are actually implemented.
-
- 11.7.
- -----
-
- For MAKE-PACKAGE, the default value of the :USE argument is ("LISP" "CLOS").
-
- The CLtL2 macro DEFPACKAGE is implemented.
-
- 11.8.
- -----
-
- The function REQUIRE receives as optional argument either a pathname or a
- list of pathnames: files to be loaded if the required module is not already
- in memory.
-
-
- CHAPTER 12: Numbers
- -------------------
-
- The single and double float formats are those of the IEEE standard (1981),
- except that CLISP does not support features like +0, -0, +inf, -inf, gradual
- underflow, NaN, etc. (Common Lisp does not make use of these features.)
-
- The default number of mantissa bits in long floats is given by the place
- (LONG-FLOAT-DIGITS).
- Example: (SETF (LONG-FLOAT-DIGITS) 3322) sets the default precision of long
- floats to 1000 decimal digits.
-
- 12.1.
- -----
-
- Complex numbers can have a real part and an imaginary part of different
- types. If the imaginary part is EQL to 0, the number is automatically
- converted to a real number. (Cf. CLtL1 p. 195)
- This has the advantage that (let ((x (sqrt -9.0))) (* x x))
- - instead of evaluting to #C(-9.0 0.0), with x = #C(0.0 3.0) -
- evaluates to #C(-9.0 0) = -9.0, with x = #C(0 3.0).
-
- Coercions on operations involving different types:
- The result of an arithmetic operation whose arguments are of different float
- types is rounded to the float format of the shortest (least precise) of the
- arguments.
- rational -> long float -> double float -> single float -> short float
- (in contrast to CLtL1 p. 195!)
- Rationale:
- See it mathematically. Add intervals:
- {1.0 +/- 1e-8} + {1.0 +/- 1e-16} = {2.0 +/- 1e-8}
- So, if we add 1.0s0 and 1.0d0, we should get 2.0s0.
- Shortly:
- Do not suggest accuracy of a result by giving it a precision that is
- greater than its accuracy.
- Example:
- (- (+ 1.7 pi) pi) should not return 1.700000726342836417234L0,
- it should return 1.7f0 (or 1.700001f0 if there were rounding errors).
- Experience:
- If in a computation using thousands of short floats, a long float (like pi)
- happens to be used, the long precision should not propagate throughout all
- the intermediate values. Otherwise, the long result would look precise,
- but its accuracy is only that of a short float; furthermore much
- computation time would be lost by calculating with long floats when only
- short floats would be needed.
-
- When rational numbers are to be converted to floats (due to FLOAT, COERCE,
- SQRT or a transcendental function), the result type is given by the variable
- *DEFAULT-FLOAT-FORMAT*.
-
- The macro WITHOUT-FLOATING-POINT-UNDERFLOW:
- (without-floating-point-underflow {form}*)
- executes the forms, with errors of type FLOATING-POINT-UNDERFLOW inhibited.
- Floating point operations will silently return zero instead of signalling
- an error of type FLOATING-POINT-UNDERFLOW.
-
- 12.4.
- -----
-
- (LCM), called without arguments, returns 1, which is the neutral element of
- composition with LCM.
-
- (! n) returns the factorial of n, n a nonnegative integer.
-
- (EXQUO x y) returns the quotient x/y of two integers x,y, and checks that it
- is an integer. (This is more efficient than /.)
-
- (XGCD x1 ... xn) returns the values g, c1, ..., cn, where
- g is the greatest common divisor of the integers x1,...,xn,
- and c1,...,cn are integer coefficients such that
- g = (GCD x1 ... xn) = (+ (* c1 x1) ... (* cn xn))
-
- 12.5.1.
- -------
-
- (EXPT base exponent) is not very precise if exponent has large absolute
- value.
-
- (LOG number base) signals an error if base = 1.
-
- 12.5.2.
- -------
-
- The value of PI is a long float with the precision given by
- (LONG-FLOAT-DIGITS). When this precision is changed, the value of PI is
- automatically recomputed. Therefore PI is a variable, not a constant.
-
- 12.6.
- -----
-
- FLOAT-RADIX always returns 2.
-
- (FLOAT-DIGITS number digits) coerces `number' (a real number) to a floating
- point number with at least `digits' mantissa digits. The following holds:
- (>= (FLOAT-DIGITS (FLOAT-DIGITS number digits)) digits)
-
- 12.7.
- -----
-
- BOOLE-CLR = 0
- BOOLE-SET = 15
- BOOLE-1 = 10
- BOOLE-2 = 12
- BOOLE-C1 = 5
- BOOLE-C2 = 3
- BOOLE-AND = 8
- BOOLE-IOR = 14
- BOOLE-XOR = 6
- BOOLE-EQV = 9
- BOOLE-NAND = 7
- BOOLE-NOR = 1
- BOOLE-ANDC1 = 4
- BOOLE-ANDC2 = 2
- BOOLE-ORC1 = 13
- BOOLE-ORC2 = 11
-
- 12.10.
- ------
-
- MOST-POSITIVE-FIXNUM = 2^24-1 = 16777215
- MOST-NEGATIVE-FIXNUM = -2^24 = -16777216
-
- Together with PI, the other long float constants MOST-POSITIVE-LONG-FLOAT,
- LEAST-POSITIVE-LONG-FLOAT, LEAST-NEGATIVE-LONG-FLOAT,
- MOST-NEGATIVE-LONG-FLOAT, LONG-FLOAT-EPSILON, LONG-FLOAT-NEGATIVE-EPSILON
- are recomputed whenever (LONG-FLOAT-DIGITS) is changed. They are variables,
- not constants.
-
-
- CHAPTER 13: Characters
- ----------------------
-
- See first above: 2.2.
-
- 13.1.
- -----
-
- CHAR-CODE-LIMIT = 256
- CHAR-FONT-LIMIT = 16
- CHAR-BITS-LIMIT = 16
-
- 13.2.
- -----
-
- String-chars are those characters with font = 0 and bits = 0.
-
- The graphic characters have been described above.
-
- The standard characters are #\Newline and those graphic characters with a
- code between 32 and 126 (inclusive).
-
- The alphabetic characters are these string-chars:
- ABCDEFGHIJKLMNOPQRSTUVWXYZ
- abcdefghijklmnopqrstuvwxyz
- and the international alphabetic characters from the character set:
- ╟ⁿΘΓΣαστΩδΦ∩ε∞─┼╔µ╞⌠÷≥√∙ ╓▄▀ßφ≤·±╤¬║π⌡╪°└├╒ etc.
-
- The functions CHAR-EQUAL, CHAR-NOT-EQUAL, CHAR-LESSP, CHAR-GREATERP,
- CHAR-NOT-GREATERP, CHAR-NOT-LESSP ignore bits and font attributes of their
- arguments.
-
- 13.4.
- -----
-
- The string chars that are not graphic chars and the space character have
- names:
- (code-char #x00) = #\Null = #\Nul
- (code-char #x01) = #\Soh
- (code-char #x02) = #\Stx
- (code-char #x03) = #\Etx
- (code-char #x04) = #\Eot
- (code-char #x05) = #\Enq
- (code-char #x06) = #\Ack
- (code-char #x07) = #\Bell = #\Bel
- (code-char #x08) = #\Backspace = #\Bs
- (code-char #x09) = #\Tab = #\Ht
- (code-char #x0A) = #\Newline = #\Nl = #\Linefeed
- (code-char #x0B) = #\Vt
- (code-char #x0C) = #\Page = #\Np
- (code-char #x0D) = #\Return = #\Cr
- (code-char #x0E) = #\So
- (code-char #x0F) = #\Si
- (code-char #x10) = #\Dle
- (code-char #x11) = #\Dc1
- (code-char #x12) = #\Dc2
- (code-char #x13) = #\Dc3
- (code-char #x14) = #\Dc4
- (code-char #x15) = #\Nak
- (code-char #x16) = #\Syn
- (code-char #x17) = #\Etb
- (code-char #x18) = #\Can
- (code-char #x19) = #\Em
- (code-char #x1A) = #\Sub
- (code-char #x1B) = #\Escape = #\Esc
- (code-char #x1C) = #\Fs
- (code-char #x1D) = #\Gs
- (code-char #x1E) = #\Rs
- (code-char #x1F) = #\Us
- (code-char #x20) = #\Space = #\Sp
- (code-char #x7F) = #\Rubout = #\Delete = #\Del
-
- 13.5.
- -----
-
- CHAR-CONTROL-BIT = 1
- CHAR-META-BIT = 2
- CHAR-SUPER-BIT = 4
- CHAR-HYPER-BIT = 8
-
-
- CHAPTER 14: Sequences
- ---------------------
-
- The CLtL2 function COMPLEMENT is implemented.
-
- 14.1.
- -----
-
- The result of NREVERSE is always EQ to the argument. NREVERSE on a vector
- swaps pairs of elements. NREVERSE on a list swaps the first and the last
- element and reverses the list chaining between them.
-
- 14.2.
- -----
-
- For iteration through a sequence, a macro DOSEQ, analogous to DOLIST, may be
- used instead of MAP :
- (doseq (var seqform [resultform]) {declaration}* {tag|statement}* )
-
- The CLtL2 function MAP-INTO is implemented.
-
- 14.3.
- -----
-
- REMOVE, REMOVE-IF, REMOVE-IF-NOT, REMOVE-DUPLICATES return their argument
- unchanged, if no element has to be removed.
-
- DELETE, DELETE-IF, DELETE-IF-NOT, DELETE-DUPLICATES destructively modify
- their argument: If the argument is a list, the CDR parts are modified. If
- the argument is a vector with fill pointer, the fill pointer is lowered and
- the remaining elements are compacted below the new fill pointer.
-
- 14.5.
- -----
-
- SORT and STABLE-SORT have two additional keywords :START and :END :
- (SORT sequence predicate &key :key :start :end)
- (STABLE-SORT sequence predicate &key :key :start :end)
-
- SORT and STABLE-SORT are identical. They implement the mergesort algorithm.
-
-
- CHAPTER 15: Lists
- -----------------
-
- 15.4.
- -----
-
- SUBLIS and NSUBLIS apply the :KEY argument to the nodes of the cons tree and
- not to the keys of the alist.
-
-
- CHAPTER 16: Hash Tables
- -----------------------
-
- 16.1.
- -----
-
- MAKE-HASH-TABLE has an additional keyword :INITIAL-CONTENTS :
- (MAKE-HASH-TABLE &key :test :initial-contents :size :rehash-size
- :rehash-threshold)
- The :INITIAL-CONTENTS argument is an alist that is used to initialize the
- new hash table.
- The :REHASH-THRESHOLD argument is ignored.
-
- For iteration through a hash table, a macro DOHASH, analogous to DOLIST, can
- be used instead of MAPHASH :
- (dohash (key-var value-var hash-table-form [resultform])
- {declaration}* {tag|statement}*
- )
-
-
- CHAPTER 17: Arrays
- ------------------
-
- 17.1.
- -----
-
- MAKE-ARRAY can return specialized arrays for the element types
- (UNSIGNED-BYTE 2), (UNSIGNED-BYTE 4), (UNSIGNED-BYTE 8), (UNSIGNED-BYTE 16),
- (UNSIGNED-BYTE 32) and of course BIT and STRING-CHAR.
-
- ARRAY-RANK-LIMIT is 65536 on 16-bit processors, 4294967296 on 32-bit
- processors.
-
- ARRAY-DIMENSION-LIMIT = 2^24 = 16777216
- ARRAY-TOTAL-SIZE-LIMIT = 2^24 = 16777216
-
- 17.6.
- -----
-
- An array to which another array is displaced should not be shrunk (using
- ADJUST-ARRAY) in such a way that the other array points into void space.
- This is not checked at the time ADJUST-ARRAY is called!
-
-
- CHAPTER 18: Strings
- -------------------
-
- 18.2.
- -----
-
- String comparison is based on the function CHAR<=. Therefore diphtongs do
- not obey the usual national rules. Example: "o" < "oe" < "z" < "÷".
-
-
- CHAPTER 19: Structures
- ----------------------
-
- 19.5.
- -----
-
- The :PRINT-FUNCTION option should contain a lambda expression
- (lambda (structure stream depth) (declare (ignore depth)) ...)
- This lambda expression names a function whose task is to output the external
- representation of structure onto the stream. This may be done by outputting
- text onto the stream using WRITE-CHAR, WRITE-STRING, WRITE, PRIN1, PRINC,
- PRINT, PPRINT, FORMAT and the like. The following rules must be obeyed:
- * The value of *PRINT-ESCAPE* must be respected.
- * The value of *PRINT-PRETTY* should not and cannot be respected, since the
- pretty-print mechanism is not accessible from outside.
- * The value of *PRINT-CIRCLE* need not to be respected. This is managed by
- the system. (But the print-circle mechanism handles only those objects that
- are (direct or indirect) components of structure.)
- * The value of *PRINT-LEVEL* is respected by
- WRITE, PRIN1, PRINC, PRINT, PPRINT, FORMAT ~A, FORMAT ~S, FORMAT ~W and
- FORMAT ~D,~B,~O,~X,~R,~F,~E,~G,~$ with not-numerical arguments.
- Therefore the print-level mechanism works automatically if only these
- functions are used for outputting objects and if they are not called on
- objects with nesting level > 1. (The print-level mechanism does not
- recognize how many parentheses you have output. It only counts how many
- times it was called recursively.)
- * The value of *PRINT-LENGTH* must be respected, especially if you are
- outputting an arbitrary number of components.
- * The value of *PRINT-READABLY* must be respected. Remember that the values
- of *PRINT-ESCAPE*, *PRINT-LEVEL*, *PRINT-LENGTH* don't matter if
- *PRINT-READABLY* is true.
- The value of *PRINT-READABLY* is respected by PRINT-UNREADABLE-OBJECT,
- WRITE, PRIN1, PRINC, PRINT, PPRINT, FORMAT ~A, FORMAT ~S, FORMAT ~W and
- FORMAT ~D,~B,~O,~X,~R,~F,~E,~G,~$ with not-numerical arguments.
- Therefore *PRINT-READABLY* will be respected automatically if only these
- functions are used for outputting objects.
- * You need not bother about the values of *PRINT-BASE*, *PRINT-RADIX*,
- *PRINT-CASE*, *PRINT-GENSYM*, *PRINT-ARRAY*, *PRINT-CLOSURE*, *PRINT-RPARS*,
- *PRINT-INDENT-LISTS*.
-
- The :INHERIT option is exactly like :INCLUDE except that it doesn't create
- new accessors for the inherited slots. Use this option to avoid the problems
- that occur when using the same :CONC-NAME for the new and the inherited
- structure.
-
-
- CHAPTER 20: The Evaluator
- -------------------------
-
- As in Scheme, the Macro (THE-ENVIRONMENT) returns the current lexical
- environment. This works only in interpreted code and is not compilable!
-
- (EVAL-ENV form [env]) evaluates a form in a given lexical environment, just
- if the form had been part of the program text that environment came from.
-
-
- CHAPTER 21: Streams
- -------------------
-
- 21.1.
- -----
-
- Input through *TERMINAL-IO* uses the GNU readline library. Arrow keys can be
- used to move within the input history. The Tab key completes the symbol's
- name that is being typed.
- See readline.dvi for a complete description of the key bindings.
- The GNU readline library is not used if standard input and standard output do
- not both refer to the same terminal.
-
- *TERMINAL-IO* is not the only stream that communicates directly with the
- user: During execution of the body of a (WITH-KEYBOARD . body) form,
- *KEYBOARD-INPUT* is the stream that reads the keystrokes from the keyboard.
- It returns every keystroke in detail, as character with the following bits:
- CHAR-CODE the Ascii code for standard keys,
- for non-standard keys:
- F1 -> #\F1, ..., F10 -> #\F10, F11 -> #\F11, F12 -> #\F12,
- Insert -> #\Insert, Delete -> #\Delete, Center -> #\Center,
- Home -> #\Home, End -> #\End, PgUp -> #\PgUp, PgDn -> #\PgDn,
- Arrow keys -> #\Up, #\Down, #\Left, #\Right.
- CONTROL if pressed together with the Control key.
- This keyboard input is not echoed on the screen.
- During execution of a (WITH-KEYBOARD . body) form, no input from *TERMINAL-IO*
- or any synonymous stream should be requested.
-
- 21.2.
- -----
-
- The macro WITH-OUTPUT-TO-PRINTER
- (with-output-to-printer (var) {declaration}* {form}*)
- binds the variable var to an output stream that sends its output to the
- printer.
-
- (MAKE-PIPE-INPUT-STREAM command) returns an input stream that will supply the
- output from the execution of the given operating system command.
- See also (SHELL command).
-
- (MAKE-PIPE-OUTPUT-STREAM command) returns an output stream that will pass its
- output as input to the execution of the given operating system command.
- See also (SHELL command).
-
- (MAKE-PIPE-IO-STREAM command) returns three values. The first value is a
- bidirectional stream that will simultaneously pass its output as input to
- the execution of the given operating system command and supply the output
- from this command as input. The second and third value will be the input
- stream and the output stream that make up the I/O stream, respectively.
- Note that they must be closed individually.
- Warning: Improper use of this function can lead to deadlocks. You use it at
- your own risk!
- A deadlock occurs if the command and your program either both try to read
- from each other at the same time or both try to write to each other at
- the same time. To avoid deadlocks, it is recommended that you fix a protocol
- between the command and your program and avoid any hidden buffering: Use
- READ-CHAR, READ-CHAR-NO-HANG, LISTEN instead of READ-LINE and READ on the
- input side, and complete every output operation by a FINISH-OUTPUT. The same
- cautions must apply to the called command as well.
- See also (SHELL command).
-
- Generic streams are user programmable streams. The programmer interface:
-
- (MAKE-GENERIC-STREAM controller) returns a generic stream.
-
- (GENERIC-STREAM-CONTROLLER stream)
- returns a private object to which generic stream methods dispatch.
- The typical usage is to retrieve the object originally provided by the
- user in MAKE-GENERIC-STREAM.
-
- (GENERIC-STREAM-P stream)
- determines whether a stream is a generic stream, returning T if it is,
- NIL otherwise.
-
- In order to specify the behaviour of a generic stream, the user must define
- CLOS methods on the following CLOS generic functions. The function
- GENERIC-STREAM-XYZ corresponds to the Common Lisp function XYZ. They all
- take a controller and some number of arguments.
-
- (GENERIC-STREAM-READ-CHAR controller)
- (GENERIC-STREAM-READ-BYTE controller)
- These generic functions should return NIL at end of file.
- Takes one argument, the controller object.
- (GENERIC-STREAM-LISTEN controller)
- Returns -1 for EOF, 0 for character pending, and 1 for none.
- Takes one argument, the controller object.
- (GENERIC-STREAM-WRITE-CHAR controller ch)
- First argument is the controller object.
- Second argument is the character to be written.
- (GENERIC-STREAM-WRITE-BYTE controller by)
- First argument is the controller object.
- Second argument is the integer to be written.
- (GENERIC-STREAM-WRITE-STRING controller string start len)
- Called with argument list (controller string start len),
- this function shall write
- (subseq (the string string) start (+ start len))
- First argument is the controller object.
- (GENERIC-STREAM-CLEAR-INPUT controller)
- (GENERIC-STREAM-CLEAR-OUTPUT controller)
- (GENERIC-STREAM-FINISH-OUTPUT controller)
- (GENERIC-STREAM-FORCE-OUTPUT controller)
- (GENERIC-STREAM-CLOSE controller)
- Takes one argument, the controller object.
-
- 21.3.
- -----
-
- The CLtL2 function OPEN-STREAM-P is implemented.
-
- CLOSE ignores its :ABORT argument.
-
- The CLtL2 functions BROADCAST-STREAM-STREAMS, CONCATENATED-STREAM-STREAMS,
- ECHO-STREAM-INPUT-STREAM, ECHO-STREAM-OUTPUT-STREAM, SYNONYM-STREAM-SYMBOL,
- TWO-WAY-STREAM-INPUT-STREAM, TWO-WAY-STREAM-OUTPUT-STREAM are implemented.
-
-
- CHAPTER 22: Input/Output
- ------------------------
-
- 22.1.2.
- -------
-
- A "reserved token", i.e. a token that has potential number syntax but cannot
- be interpreted as a number, is interpreted as symbol when being read. (CLtL1
- p. 341)
-
- When a token with package markers is read, then (CLtL1 p. 343/344) no
- checking is done whether the package part and the symbol-name part do not
- have number syntax. (What's the purpose of this check?) So we consider
- tokens like USER:: or :1 or LISP::4711 or 21:3 as symbols.
-
- 22.1.3.
- -------
-
- The backquote read macro also works when nested. Example:
- (eval ``(,#'(lambda () ',a) ,#'(lambda () ',b)))
- = (eval `(list #'(lambda () ',a) #'(lambda () ',b)))
- = (eval (list 'list (list 'function (list 'lambda nil (list 'quote a)))
- (list 'function (list 'lambda nil (list 'quote b)))
- ) )
-
- Multiple backquote combinations like ,,@ or ,@,@ are not implemented. Their
- use would be confusing anyway.
-
- 22.1.4.
- -------
-
- #\ allows inputting characters of arbitrary code: #\Code231 yields the
- character (code-char 231.).
-
- Additional read dispatch macros:
- * #Y is used to read compiled functions.
- * #" is used to read pathnames:
- #"test.lsp" is the value of (pathname "test.lsp")
-
- 22.1.5.
- -------
-
- Is it impossible to get the read macro function of a dispatch macro
- character like #\# using GET-MACRO-CHARACTER.
-
- The CLtL2 place READTABLE-CASE is implemented. The possible values of
- (READTABLE-CASE readtable) are :UPCASE, :DOWNCASE and :PRESERVE.
-
- 22.1.6.
- -------
-
- In absence of SYS::WRITE-FLOAT, floating point numbers are output in radix 2.
-
- If *PRINT-READABLY* is true, *READ-DEFAULT-FLOAT-FORMAT* has no influence on
- the way floating point numbers are printed.
-
- Pathnames are written according to the syntax #"namestring" if
- *PRINT-ESCAPE* /= NIL. If *PRINT-ESCAPE* = NIL, only the namestring is
- printed.
-
- *PRINT-CASE* controls the output not only of symbols, but also of characters
- and some #<...> objects.
-
- *PRINT-PRETTY* is initially = NIL but set to T in config.lsp. This makes
- screen output prettier.
-
- *PRINT-ARRAY* is initially = T.
-
- An additional variable *PRINT-CLOSURE* controls whether compiled and
- interpreted functions (closures) are output in detailed form. If
- *PRINT-CLOSURE* /= NIL, compiled closures are output in #Y syntax the reader
- understands. *PRINT-CLOSURE* is initially = NIL.
-
- An additional variable *PRINT-RPARS* controls the output of right (closing)
- parentheses. If *PRINT-RPARS* /= NIL, closing parentheses which don't fit
- onto the same line as the the corresponding opening parenthesis are output
- just below their corresponding opening parenthesis, in the same column.
- *PRINT-RPARS* is initially = T.
-
- An additional variable *PRINT-INDENT-LISTS* controls the indentation of lists
- that span more than one line. It specifies by how many characters items
- within the list will be indented relative to the beginning of the list.
- *PRINT-INDENT-LISTS* is initially = 2.
-
- The CLtL2 macro WITH-STANDARD-IO-SYNTAX is implemented.
-
- 22.2.1.
- -------
-
- The function READ-CHAR-SEQUENCE performs multiple READ-CHAR operations:
- (READ-CHAR-SEQUENCE sequence stream [:start] [:end]) fills the
- subsequence of sequence specified by :start and :end with characters
- consecutively read from stream. It returns the index of the first element
- of sequence that was not updated (= end or < end if the stream reached its
- end).
- This function is especially efficient if sequence is a string and stream is
- a file stream with element type STRING-CHAR, a pipe stream or a string input
- stream.
-
- 22.2.2.
- -------
-
- The function READ-BYTE-SEQUENCE performs multiple READ-BYTE operations:
- (READ-BYTE-SEQUENCE sequence stream [:start] [:end]) fills the
- subsequence of sequence specified by :start and :end with integers
- consecutively read from stream. It returns the index of the first element
- of sequence that was not updated (= end or < end if the stream reached its
- end).
- This function is especially efficient if sequence is a
- (VECTOR (UNSIGNED-BYTE 8)) and stream is a file stream with element type
- (UNSIGNED-BYTE 8) or a pipe stream.
-
- 22.3.1.
- -------
-
- The functions WRITE and WRITE-TO-STRING have an additional keyword :CLOSURE
- that can be used to bind *PRINT-CLOSURE*.
-
- The CLtL2 macro PRINT-UNREADABLE-OBJECT is implemented.
-
- The function WRITE-CHAR-SEQUENCE performs multiple WRITE-CHAR operations:
- (WRITE-CHAR-SEQUENCE sequence stream [:start] [:end]) outputs the characters
- of the subsequence of sequence specified by :start and :end to stream.
- It returns sequence.
- This function is especially efficient if sequence is a string and stream is
- a file stream with element type STRING-CHAR or a pipe stream.
-
- 22.3.2.
- -------
-
- The function WRITE-BYTE-SEQUENCE performs multiple WRITE-BYTE operations:
- (WRITE-BYTE-SEQUENCE sequence stream [:start] [:end]) outputs the integers
- of the subsequence of sequence specified by :start and :end to stream.
- It returns sequence.
- This function is especially efficient if sequence is a
- (VECTOR (UNSIGNED-BYTE 8)) and stream is a file stream with element type
- (UNSIGNED-BYTE 8) or a pipe stream.
-
- 22.3.3.
- -------
-
- The FORMAT option ~W is analogous to ~A and ~S, but avoids binding of
- *PRINT-ESCAPE*. (FORMAT stream "~W" object) is equivalent to
- (WRITE object :stream stream).
-
- FORMAT ~R and FORMAT ~:R can output only integers in the range |n| < 10^66.
- The output is in English, according to the American conventions, and these
- conventions are identical to the British conventions only in the range
- |n| < 10^9.
-
- FORMAT ~:@C does not output the character itself, only the instruction how
- to type the character.
-
- For FORMAT ~E and FORMAT ~G, the value of *READ-DEFAULT-FLOAT-FORMAT* doesn't
- matter if *PRINT-READABLY* is true.
-
- FORMAT ~T can determine the current column of any stream.
-
-
- CHAPTER 23: File System Interface
- ---------------------------------
-
- 23.1.
- -----
-
- For most operations, pathnames denoting files and pathnames denoting
- directories can not be used interchangeably.
- For example, #"FOO/BAR" denotes the file BAR in the directory FOO, while
- #"FOO/BAR/" denotes the subdirectory BAR of the directory FOO.
- This is especially important for the functions DIRECTORY, DIR, CD, MAKE-DIR,
- DELETE-DIR.
-
- The minimum filename syntax that may be used portably is:
- "xxx" for a file with name xxx,
- "xxx.yy" for a file with name xxx and type yy,
- ".yy" for a pathname with type yy and no name specified.
- Hereby xxx denote 1 to 8 characters, and yy denote 1 to 3 characters, each of
- which being either alphanumerical or the underscore #\_.
- Other properties of pathname syntax vary between operating systems.
-
- 23.1.1.
- -------
-
- Pathname components:
- HOST always NIL
- DEVICE always NIL
- DIRECTORY (startpoint . subdirs) where
- startpoint = :RELATIVE | :ABSOLUTE
- subdirs = () | (subdir . subdirs)
- subdir = :WILD-INFERIORS (means "**" or "...", all subdirectories) or
- subdir = simple string, may contain wildcard characters ? and *
- NAME NIL or
- simple string, may contain wildcard characters ? and *
- (may also be specified as :WILD)
- TYPE NIL or
- simple string, may contain wildcard characters ? and *
- (may also be specified as :WILD)
- VERSION always NIL (may also be specified as :WILD or :NEWEST)
-
- A UNIX filename is split into name and type according to the following rule:
- if there is no '.' in the filename, then the name is everything, type = NIL;
- if there is a '.', then name is the part before and type the part after
- the last dot.
-
- When a pathname is to be fully specified (no wildcards), that means that
- no :WILD, :WILD-INFERIORS is allowed, no wildcard characters are allowed in
- the strings, and NAME = NIL may not be allowed either.
-
- External notation: server:sub1.typ/sub2.typ/name.typ
- using defaults: sub1.typ/sub2.typ/name.typ
- or name.typ
- or sub1.typ/**/sub3.typ/x*.lsp
- or similar.
-
- The wildcard characters: '*' matches any sequence of characters, '?' matches
- any one character.
-
- Due to the name/type splitting rule, there are pathnames that can't result
- from PARSE-NAMESTRING. To get a pathname whose type contains a dot or whose
- name contains a dot and whose type is NIL, MAKE-PATHNAME must be used.
- Example: (MAKE-PATHNAME :NAME ".profile").
-
- 23.1.2.
- -------
-
- External notation of pathnames (cf. PARSE-NAMESTRING and NAMESTRING),
- of course without spaces, [,],{,}:
- [ / ] / denotes absolute pathnames
- { name / } each one a subdirectory
- [ name [. type] ] filename with type (extension)
-
- Name and type may be character sequences of any length (consisting of
- printing ASCII characters, except '/').
-
- NAMESTRING has an optional flag argument: (NAMESTRING pathname T) returns an
- external notation suitable for passing to the operating system or other
- programs.
-
- 23.1.4.
- -------
-
- The CLtL2 functions WILD-PATHNAME-P, PATHNAME-MATCH-P and TRANSLATE-PATHNAME
- are implemented.
-
- PATHNAME-MATCH-P does not interpret missing components as wild.
-
- TRANSLATE-PATHNAME has two additional keywords:
- (TRANSLATE-PATHNAME source from-wildname to-wildname &key :all :merge)
- If :ALL is specified and non-NIL, a list of all resulting pathnames,
- corresponding to all matches of (PATHNAME-MATCH-P source from-wildname),
- is returned. If :MERGE is specified and NIL, unspecified pieces of to-pathname
- are not replaced by corresponding pieces of source.
-
- 23.1.5.
- -------
-
- The functions LOGICAL-PATHNAME, TRANSLATE-LOGICAL-PATHNAME,
- LOGICAL-PATHNAME-TRANSLATIONS, (SETF LOGICAL-PATHNAME-TRANSLATIONS),
- LOAD-LOGICAL-PATHNAME-TRANSLATIONS, COMPILE-FILE-PATHNAME are implemented.
-
- RENAME-FILE always returns a non-logical pathname as its first value.
-
- 23.1.6.
- -------
-
- (PARSE-NAMESTRING string [host [defaults]]) returns a logical pathname only
- if host is a logical host or host is NIL and defaults is a logical pathname.
- To construct a logical pathname from a string, the function LOGICAL-PATHNAME
- can be used.
-
- (MERGE-PATHNAMES string [defaults]) returns a logical pathname only if
- defaults is a logical pathname. To construct a logical pathname from a string,
- the function LOGICAL-PATHNAME can be used.
-
- 23.2.
- -----
-
- OPEN cannot handle files of size >= 16 MB.
-
- The file streams returned by OPEN are buffered for regular files and
- unbuffered for special files.
-
- 23.3.
- -----
-
- PROBE-FILE can not be used to check whether a directory exists. Use the
- function DIRECTORY for this purpose.
-
- FILE-AUTHOR always returns NIL.
-
- 23.4.
- -----
-
- LOAD has two additional keywords :ECHO and :COMPILING.
- (LOAD filename &key :verbose :print :echo :if-does-not-exist :compiling)
- :VERBOSE T causes LOAD to emit a short message that a file is being loaded.
- The default is *LOAD-VERBOSE*, which is initially = T.
- :PRINT T causes LOAD to print the value of each form.
- The default is *LOAD-PRINT*, which is initially = NIL.
- :ECHO T causes the input from the file to be echoed to *STANDARD-OUTPUT*
- (normally to the screen). Should there be an error in the file,
- you can see at one glance where it is.
- The default is *LOAD-ECHO*, which is initially = NIL.
- :COMPILING T causes each form read to be compiled on the fly. The compiled
- code is executed at once and - in contrast to COMPILE-FILE -
- not written to a file.
-
- The CLtL2 variables *LOAD-PATHNAME* and *LOAD-TRUENAME* are implemented.
-
- The variable *LOAD-PATHS* contains a list of directories where program files
- are searched - additionally to the specified or current directory - by LOAD,
- REQUIRE, COMPILE-FILE.
-
- 23.5.
- -----
-
- (DIRECTORY [pathname [:full] [:circle]]) can run in two modes:
- * If pathname contains no name or type component, a list of all matching
- directories is produced.
- * Otherwise a list of all matching files is returned. If the :FULL argument
- is /= NIL, this contains additional information: for each matching file
- you get a list of at least four elements
- (file-pathname file-truename file-write-date-as-decoded-time file-length).
- If the :CIRCLE argument is /= NIL, the function avoids endless loops that
- may result from symbolic links.
-
- (DIR [pathname]) is like DIRECTORY, but displays the pathnames instead of
- returning them. (DIR) shows the contents of the current directory.
-
- (CD [pathname]) manages the current directory.
- (CD pathname) sets it, (CD) returns it.
-
- (DEFAULT-DIRECTORY) is equivalent to (CD), (SETF (DEFAULT-DIRECTORY) pathname)
- is equivalent to (CD pathname).
-
- (MAKE-DIR directory-pathname) creates a new subdirectory.
-
- (DELETE-DIR directory-pathname) removes an (empty) subdirectory.
-
- (EXECUTE programfile arg1 arg2 ...) executes an external program. Its name
- is programfile. It is given the strings arg1, arg2, ... as arguments.
-
- (SHELL [command]) calls the operating system's shell.
- (SHELL) calls the shell for interactive use. (SHELL command) calls the shell
- only for execution of the one given command.
-
- The functions RUN-SHELL-COMMAND and RUN-PROGRAM are a general interface to
- SHELL and the above:
- (RUN-SHELL-COMMAND command [:input] [:output] [:if-output-exists])
- runs a shell command.
- (RUN-PROGRAM program [:arguments] [:input] [:output] [:if-output-exists])
- runs an external program.
- The command argument specifies the shell command.
- The program argument specifies the program. The directories listed in the
- PATH environment veriable will be searched for it.
- The :arguments argument specifies a list of arguments (strings) that are
- given to the program.
- The :input argument specifies where the program's input is to come from:
- either :TERMINAL (the standard input) or :STREAM
- (a Lisp stream to be created) or a pathname (an
- input file) or NIL (no input at all).
- The :output argument specifies where the program's output is to be sent
- to: either :TERMINAL (the standard output) or :STREAM
- (a Lisp stream to be created) or a pathname (an
- output file) or NIL (ignore the output).
- The :if-output-exists argument specifies what to do if the :output file
- already exists. The possible values are :overwrite,
- :append, :error, with the same meaning as for OPEN.
- If :STREAM was specified for :input or :output, a Lisp stream is returned.
- If :STREAM was specified for :input and :output, three Lisp streams are
- returned, as for the function MAKE-PIPE-IO-STREAM. This use of RUN-PROGRAM
- can cause deadlocks, see MAKE-PIPE-IO-STREAM.
-
-
- CHAPTER 24: Errors
- ------------------
-
- 24.1.
- -----
-
- When an error occurred, you are in a break loop. You can evaluate forms as
- usual. The HELP command (or help key if there is one) lists the available
- debugging commands.
-
-
- CHAPTER 25: Miscellaneous Features
- ----------------------------------
-
- 25.1.
- -----
-
- The compiler can be called not only by the functions COMPILE, COMPILE-FILE
- and DISASSEMBLE, also by the declaration (COMPILE).
-
- (COMPILE-FILE input-file [:output-file] [:listing]
- [:warnings] [:verbose] [:print])
- compiles a file to bytecode.
- input-file should be a pathname/string/symbol.
- The :output-file argument should be NIL or T or a pathname/string/symbol
- or an output-stream. The default is T.
- The :listing argument should be NIL or T or a pathname/string/symbol
- or an output-stream. The default is NIL.
- The :warnings argument specifies whether warnings should also appear
- on the screen.
- The :verbose argument specifies whether error messages should also
- appear on the screen.
- The :print argument specifies whether an indication which forms are
- being compiled should appear on the screen.
- The variables *COMPILE-WARNINGS*, *COMPILE-VERBOSE*, *COMPILE-PRINT* provide
- defaults for the :warnings, :verbose, :print keyword arguments, respectively.
- For each input file (default file type: #".lsp") the following files are
- generated:
- output file only if :output-file is not NIL
- default file type: #".fas"
- contents: can be loaded using the LOAD function.
- auxiliary output file only if :output-file is not NIL
- default file type: #".lib"
- contents: used by COMPILE-FILE when compiling
- a REQUIRE form referring to the input file.
- listing file only if :listing is not NIL
- default file type: #".lis"
- contents: disassembly of the output file.
- C output file only if :output-file is not NIL
- default file type: #".c"
- contents: foreign function interface
- this file is deleted if it is empty.
-
- The CLtL2 variables *COMPILE-FILE-PATHNAME* and *COMPILE-FILE-TRUENAME* are
- implemented.
-
- The CLtL2 special form LOAD-TIME-VALUE is implemented. (LOAD-TIME-VALUE form)
- is like (QUOTE #,form) except that the former can be generated by macros.
-
- DISASSEMBLE can disassemble to machine code, provided that GNU gdb is present.
- In that case the argument may be a SYSTEM-FUNCTION, a FOREIGN-FUNCTION, a
- special form indicator, a symbol denoting one of these, a number, or a string.
-
- The CLtL2 function FUNCTION-LAMBDA-EXPRESSION is implemented.
- (FUNCTION-LAMBDA-EXPRESSION function) returns information about the source
- of an interpreted function: lambda-expression, lexical environment, name.
-
- 25.2.
- -----
-
- No on-line documentation is available for the system functions (yet).
-
- 25.3.
- -----
-
- (TRACE fun ...) makes the functions fun, ... traced. Syntax of fun:
- Either a symbol:
- symbol
- or a list of a symbol and some keywords and arguments (which must come in
- pairs!):
- (symbol
- [:suppress-if form] ; no trace output as long as form is true
- [:step-if form] ; invokes the stepper as soon as form is true
- [:pre form] ; evaluates form before calling the function
- [:post form] ; evaluates form after return from the function
- [:pre-break-if form] ; goes into the break loop before calling the
- ; function if form is true
- [:post-break-if form] ; goes into the break loop after return from
- ; the function if form is true
- [:pre-print form] ; prints the values of form before calling the
- ; function
- [:post-print form] ; prints the values of form after return from
- ; the function
- [:print form] ; prints the values of form both before
- ; calling and after return from the function
- )
- In all these forms you can access
- the function itself as *TRACE-FUNCTION*,
- the arguments to the function as *TRACE-ARGS*,
- the function/macro call as form as *TRACE-FORM*,
- and after return from the function
- the list of return values from the function call as *TRACE-VALUES*,
- and you can leave the function call with specified values by using RETURN.
-
- TRACE and UNTRACE are also applicable to functions (SETF symbol) and to macros,
- but not to locally defined functions and macros.
-
- The function INSPECT is not implemented.
-
- The function ROOM can only be called without arguments. It returns two values:
- the number of bytes currently occupied by Lisp objects, and the number of
- bytes that can be allocated before the next regular garbage collection occurs.
-
- The function ED calls the external editor specified by the variable *EDITOR*
- (see config.lsp).
- If using the optional package EDITOR:
- ED behaves like this only if the variable *USE-ED* is NIL.
- Otherwise ED uses an Emacs-like screen editor with multiple windows.
-
- The function UNCOMPILE does the converse of COMPILE: (UNCOMPILE function-name)
- reverts an interpreted function that has been entered or loaded in the same
- session and then compiled back to its interpreted form.
-
- 25.4.1.
- -------
-
- The timezone in a decoded time must not necessarily be an integer, but (as
- float or rational number) it should be a multiple of 1/4.
-
- INTERNAL-TIME-UNITS-PER-SECOND = 1000000.
-
- 25.4.2.
- -------
-
- The functions MACHINE-TYPE, MACHINE-VERSION, MACHINE-INSTANCE and
- SHORT-SITE-NAME, LONG-SITE-NAME should be defined by every user in his
- site-specific CONFIG.LSP file.
-
- The variable *FEATURES* initially contains the symbols
- CLISP ; this implementation
- COMMON-LISP
- CLTL1
- INTERPRETER
- COMPILER
- LOGICAL-PATHNAMES
- FFI
- LOOP
- CLOS
- AMIGA ; if hardware = Amiga and operating system = Exec/AmigaDOS
- DOS ; if hardware = PC (clone) and operating system = DOS
- OS/2 ; if hardware = PC (clone) and operating system = OS/2
- PC386 ; if hardware = PC (clone) with a 386/486
- UNIX ; if operating system = Unix
- ; (yes, in this case the
- ; hardware is irrelevant!)
-
-
- CHAPTER 26: Loop
- ----------------
-
- The CLtL2 macros LOOP and LOOP-FINISH are implemented.
-
-
- CHAPTER 27: Pretty Printing
- ---------------------------
-
- The CLtL2 macro FORMATTER is implemented.
-
-
- CHAPTER 28: Common Lisp Object System
- -------------------------------------
-
- The CLOS symbols are exported from the package "CLOS" and thus normally
- visible in all user packages. If you don't want them (for example, if you
- want to use PCL instead of CLOS), do (UNUSE-PACKAGE "CLOS").
-
- The functions
- SLOT-VALUE, SLOT-BOUNDP, SLOT-MAKUNBOUND, SLOT-EXISTS-P,
- FIND-CLASS, (SETF FIND-CLASS), CLASS-OF, CALL-NEXT-METHOD, NEXT-METHOD-P,
- CLASS-NAME, (SETF CLASS-NAME), NO-APPLICABLE-METHOD, NO-NEXT-METHOD,
- FIND-METHOD, ADD-METHOD, REMOVE-METHOD, COMPUTE-APPLICABLE-METHODS,
- METHOD-QUALIFIERS, FUNCTION-KEYWORDS, SLOT-MISSING, SLOT-UNBOUND,
- PRINT-OBJECT, DESCRIBE-OBJECT, MAKE-INSTANCE, INITIALIZE-INSTANCE,
- REINITIALIZE-INSTANCE, SHARED-INITIALIZE,
- the macros
- WITH-SLOTS, WITH-ACCESSORS, DEFCLASS, DEFMETHOD, DEFGENERIC,
- GENERIC-FUNCTION, GENERIC-FLET, GENERIC-LABELS,
- the classes
- STANDARD-CLASS, STRUCTURE-CLASS, BUILT-IN-CLASS, STANDARD-OBJECT,
- STANDARD-GENERIC-FUNCTION, STANDARD-METHOD and all predefined classes,
- and the method combination
- STANDARD
- are implemented.
-
- Deviations from CLtL2 chapter 28:
-
- DEFCLASS : It *is* required that the superclasses of a class be defined before
- the DEFCLASS form for the class is evaluated.
-
- DEFCLASS supports the option :METACLASS STRUCTURE-CLASS. This option is
- necessary in order to define a subclass of a DEFSTRUCT-defined structure type
- using DEFCLASS instead of DEFSTRUCT.
-
- The REAL type is added to the predefined classes listed in table 28-1.
-
- Only STANDARD method combination is implemented.
-
- When CALL-NEXT-METHOD is called with arguments, the rule that the ordered
- set of applicable methods must be the same as for the original arguments
- is not enforced by the implementation.
-
- CALL-NEXT-METHOD and NEXT-METHOD-P are local macros, not local functions.
- Use #'(lambda () (call-next-method)) instead of #'call-next-method if you
- really need it as a function.
-
- There is a generic function NO-PRIMARY-METHOD (analogous to
- NO-APPLICABLE-METHOD) which is called when a generic function of the class
- STANDARD-GENERIC-FUNCTION is invoked and no primary method on that generic
- function is applicable.
-
- GENERIC-FLET and GENERIC-LABELS are implemented as macros, not as special
- forms.
-
- The function ENSURE-GENERIC-FUNCTION is not implemented.
-
- ADD-METHOD can put methods into other generic functions than the one the method
- came from.
-
- PRINT-OBJECT and DESCRIBE-OBJECT are only called on objects of type
- STANDARD-OBJECT.
-
- DESCRIBE-OBJECT should not call DESCRIBE recursively as this would produce
- more information than is likely to be useful to a human reader.
-
- DOCUMENTATION still has the CLtL1 implementation.
-
- User-defined method combination is not supported.
- The sections 28.1.7.3., 28.1.7.4., the macros DEFINE-METHOD-COMBINATION,
- CALL-METHOD and the functions INVALID-METHOD-ERROR, METHOD-COMBINATION-ERROR,
- METHOD-QUALIFIERS are not implemented.
-
- The special form WITH-ADDED-METHODS is not implemented.
-
- Redefining classes is not supported.
- The sections 28.1.10., 28.1.10.1., 28.1.10.2., 28.1.10.3., 28.1.10.4. and the
- function UPDATE-INSTANCE-FOR-REDEFINED-CLASS are not implemented.
-
- Changing the class of a given instance is not supported.
- The sections 28.1.11., 28.1.11.1., 28.1.11.2., 28.1.11.3. and the functions
- CHANGE-CLASS, UPDATE-INSTANCE-FOR-DIFFERENT-CLASS, MAKE-INSTANCES-OBSOLETE are
- not implemented.
-
-
- CHAPTER 29: Conditions
- ----------------------
-
- 29.4.1.
- -------
-
- The default condition type for conditions created by SIGNAL is
- SIMPLE-CONDITION, not SIMPLE-ERROR.
-
- 29.4.4.
- -------
-
- The macro (MUFFLE-CERRORS {form}*) executes the forms. When a continuable
- error occurs, no message is printed. Instead, the CONTINUE restart is invoked.
-
- The macro (APPEASE-CERRORS {form}*) executes the forms. When a continuable
- error occurs, the error is printed as a warning and the CONTINUE restart is
- invoked.
-
- The macro (EXIT-ON-ERROR {form}*) executes the forms. When a non-continuable
- error occurs, the error is printed and CLISP terminates with error status.
-
- 29.4.7.
- -------
-
- In RESTART-CASE clauses the argument list can also be specified after the
- keyword/value pairs instead of before them. The syntax therefore is
- (RESTART-CASE form {restart-clause}*)
- with
- restart-clause ::= (restart-name arglist {keyword value}* {form}*)
- | (restart-name {keyword value}* arglist {form}*)
-
- The macro WITH-RESTARTS is like RESTART-CASE, except that the forms are
- specified after the restart clauses instead of before them, and the
- restarts created are not implicitly associated to any condition.
- (WITH-RESTARTS ({restart-clause}*) {form}*)
- is therefore equivalent to (RESTART-CASE (PROGN {form}*) {restart-clause}*).
-
- 29.4.8.
- -------
-
- COMPUTE-RESTARTS and FIND-RESTART behave as specified in dpANS: If the
- optional condition argument is not NIL, only restarts associated with that
- condition and restarts associated to no condition at all are considered.
- Therefore the effect of associating a restart to a condition is not to
- activate it, but to hide it from other conditions. This makes the syntax
- dependent implicit association performed by RESTART-CASE nearly obsolete.
-
- 29.4.9.
- -------
-
- The default condition type for conditions created by WARN is SIMPLE-WARNING,
- not SIMPLE-ERROR.
-
-
- CHAPTER 90: Platform independent Extensions
- -------------------------------------------
-
- 90.1. Saving an Image
- ---------------------
-
- The function (SAVEINITMEM [filename [:quiet] [:init-function]]) saves the
- running CLISP's memory to a file. The filename defaults to "lispinit.mem".
- If the :QUIET argument is not NIL, the startup banner and the good-bye
- message will be suppressed. The :INIT-FUNCTION argument specifies a function
- that will be executed at startup of the saved image.
-
- 90.2. Quitting Lisp
- -------------------
-
- The functions (EXIT [errorp]), (QUIT [errorp]) and (BYE [errorp])
- - all synonymous - terminate CLISP. If errorp is not NIL, CLISP aborts with
- error status, i.e. the environment is informed that the CLISP session didn't
- succeed.
-
- 90.3. The Language
- ------------------
-
- The language CLISP uses to communicate with the user can be either
- ENGLISH or DEUTSCH (i.e. german) or FRANCAIS (i.e. french). The macros
- ENGLISH, DEUTSCH, FRANCAIS and LANGUAGE-CASE produce code that depends on
- the language:
- (ENGLISH english-form DEUTSCH deutsch-form FRANCAIS francais-form)
- - and all permutations of this - evaluates all of english-form, deutsch-form,
- francais-form in no particular order and returns the evaluation result
- corresponding to the user language.
- (LANGUAGE-CASE {clause}*) executes the clause (analogous to CASE) that
- corresponds to the user language.
- The language itself is the value of
- (ENGLISH 'ENGLISH DEUTSCH 'DEUTSCH FRANCAIS 'FRANCAIS).
-
- 90.4. Finalization
- ------------------
-
- Calling (FINALIZE object function) has the effect that when the specified
- object is being garbage collected, (FUNCALL function object) will be executed.
-
- Calling (FINALIZE object function guardian) has a similar effect, but only
- as long as the "guardian" has not been garbage collected: When object is
- being garbage collected, (FUNCALL function object guardian) will be executed.
- If the guardian is garbage collected before object is, nothing happens.
-
- Note: The time when "object is being garbage collected" is not defined
- deterministically. (Actually, it possibly never occurs.) It denotes a moment
- at which no references to object exist from other Lisp objects. When the
- function is called, object (and possibly guardian) enter the "arena of live
- Lisp objects" again.
-
- No finalization request will be executed more than once.
-
-
- CHAPTER 91: The Debugger and Stepper
- ------------------------------------
-
- The debugger may be invoked through the functions INVOKE-DEBUGGER, BREAK,
- SIGNAL, ERROR, CERROR, WARN. The stepper is invoked through the macro STEP.
- Debugger and stepper execute subordinate READ - EVAL - PRINT loops (called
- "break loops") which are analogous to the main READ - EVAL - PRINT loop except
- for the prompt and the set of available commands. Commands must be typed
- literally, without surrounding quotes or white space.
-
- Commands common to the main loop, the debugger and the stepper:
- Help prints a list of available commands.
-
- Commands common to the debugger and the stepper:
- Abort and
- Unwind abort to the next most recent READ - EVAL - PRINT loop.
-
- The stack is organized into frames and other stack elements. Usually every
- invocation of an interpreted function and every evaluation of an interpreted
- form corresponds to one stack frame. Special forms such as LET, LET*,
- UNWIND-PROTECT and CATCH produce special kinds of stack frames.
-
- In a break loop there is a current stack frame, which is initially the most
- recent stack frame but can be moved using the debugger commands Up and Down.
-
- Evaluation of forms in a break loop occurs in the lexical environment of the
- current stack frame but in the dynamic environment of the debugger's caller.
- This means that to inspect or modify a lexical variable all you have to do
- is to move to the current stack frame just below the frame that corresponds
- to the form or the function call that binds that variable.
-
- There is a current "stack mode" which defines in how much detail the stack
- is shown by the stack related debugger commands.
-
- Commands common to the debugger and the stepper:
- Mode-1 sets the current mode to 1: all the stack elements are
- considered. This mode is fine for debugging compiled functions.
- Mode-2 sets the current mode to 2: all the frames are considered.
- Mode-3 sets the current mode to 3: only lexical frames (frames that
- correspond to special forms that modify the lexical environment)
- are considered.
- Mode-4 sets the current mode to 4 (the default): only EVAL and APPLY
- frames are considered. Every evaluation of a form in the
- interpreter corresponds to an EVAL frame.
- Mode-5 sets the current mode to 5: only APPLY frames are considered.
- Every invocation of an interpreted function corresponds to one
- APPLY frame.
- Where shows the current stack frame.
- Up goes up one frame, i.e. to the caller if in mode-5
- Down does down one frame, i.e. to the callee if in mode-5
- Top goes to top frame, i.e. to the top-level form if in mode-4
- Bottom goes to bottom (most recent) frame, i.e. most probably to the
- form or function that caused the debugger to be entered.
- Backtrace lists the stack in current mode, bottom frame first, top frame
- last.
- Backtrace-1 lists the stack in mode 1.
- Backtrace-2 lists the stack in mode 2.
- Backtrace-3 lists the stack in mode 3.
- Backtrace-4 lists the stack in mode 4.
- Backtrace-5 lists the stack in mode 5.
- If the current stack frame is an EVAL or APPLY frame, the following commands
- are available as well:
- Break+ sets a breakpoint in the current frame. When the corresponding
- form or function will be left, the debugger will be entered
- again, with the variable *TRACE-VALUES* containing a list of
- its values.
- Break- removes a breakpoint from the current frame.
- Redo re-evaluates the corresponding form or function call. This
- command can be used to restart parts of a computation without
- aborting it entirely.
- Return leaves the current frame. You will be prompted for the
- return values.
-
- Commands specific to the debugger:
- Continue continues evaluation of the program.
-
- Commands specific to the stepper:
- Step step into a form: evaluate this form in single step mode
- Next step over a form: evaluate this form at once
- Over step over this level: evaluate at once up to the next return
- Continue switch off single step mode, continue evaluation
-
- The stepper is usually used like this: If some form returns a strange value
- or results in an error, call (STEP form) and navigate using the commands
- Step and Next until you reach the form you regard as responsible. If you
- are too fast (execute Next once and get the error), there is no way back; you
- have to restart the entire stepper session. If you are too slow (stepped into
- a function or a form which certainly is OK), a couple of Next commands or one
- Over command will help.
-
-
- CHAPTER 99: Platform specific Extensions
- ----------------------------------------
-
- 99.2. Random Screen Access
- --------------------------
-
- (SCREEN:MAKE-WINDOW)
- returns a "window stream". As long as this stream is open, the terminal
- is in cbreak/noecho mode. *TERMINAL-IO* shouldn't be used for input or
- output during this time. (Use WITH-KEYBOARD and *KEYBOARD-INPUT* instead.)
-
- (SCREEN:WITH-WINDOW . body)
- binds SCREEN:*WINDOW* to a window stream and executes body. The stream is
- guaranteed to be closed when the body is left. During its execution,
- *TERMINAL-IO* shouldn't be used, as above.
-
- (SCREEN:WINDOW-SIZE window-stream)
- returns the window's size, as two values:
- height (= Ymax+1) and width (= Xmax+1).
-
- (SCREEN:WINDOW-CURSOR-POSITION window-stream)
- returns the position of the cursor in the window, as two values:
- line (>=0, <=Ymax, 0 means top), column (>=0, <=Xmax, 0 means left margin).
-
- (SCREEN:SET-WINDOW-CURSOR-POSITION window-stream line column)
- sets the position of the cursor in the window.
-
- (SCREEN:CLEAR-WINDOW window-stream)
- clears the window's contents and puts the cursor in the upper left corner.
-
- (SCREEN:CLEAR-WINDOW-TO-EOT window-stream)
- clears the window's contents from the cursor position to the end of window.
-
- (SCREEN:CLEAR-WINDOW-TO-EOL window-stream)
- clears the window's contents from the cursor position to the end of line.
-
- (SCREEN:DELETE-WINDOW-LINE window-stream)
- removes the cursor's line, moves the lines below it up by one line and
- clears the window's last line.
-
- (SCREEN:INSERT-WINDOW-LINE window-stream)
- inserts a line at the cursor's line, moving the lines below it down by
- one line.
-
- (SCREEN:HIGHLIGHT-ON window-stream)
- switches highlighted output on.
-
- (SCREEN:HIGHLIGHT-OFF window-stream)
- switches highlighted output off.
-
- (SCREEN:WINDOW-CURSOR-ON window-stream)
- makes the cursor visible, a cursor block in most implementations.
-
- (SCREEN:WINDOW-CURSOR-OFF window-stream)
- makes the cursor invisible, in implementations where this is possible.
-
- 99.3. External Modules
- ----------------------
-
- Managing external modules for CLISP
- ===================================
-
- CLISP has a facility for adding external modules (written in C, for example).
- It is invoked through clisp-link.
-
- A module is a piece of external code which defines extra Lisp objects, symbols
- and functions. A module name must consist of the characters A-Z,a-z,_,0-9. The
- module name "clisp" is reserved. Normally a module name is derived from the
- corresponding file name.
-
- clisp-link needs a directory containing:
- modules.d
- modules.c
- module.cc
- clisp.h
- clisp-link expects to find these files in a subdirectory linkkit/ of the
- current directory. This can be overridden by the environment variable
- CLISP_LINKKIT.
-
- clisp-link operates on CLISP linking sets and on module sets.
-
- A linking set is a directory containing:
- makevars some /bin/sh commands, setting the variables
- CC the C compiler
- CFLAGS flags for the C compiler, when compiling
- CLFLAGS flags for the C compiler, when linking
- LIBS libraries to use when linking
- X_LIBS additional X window system libraries to use
- RANLIB the ranlib command
- FILES the list of files needed when linking
- modules.h the list of modules contained in this linking set
- all the FILES listed in makevars
- lisp.run the executable
- lispinit.mem the memory image
- To run a clisp contained in some linking set <dir>, call
- "<dir>/lisp.run -M <dir>/lispinit.mem".
-
- A module set is a directory containing:
- link.sh some /bin/sh commands, which prepare the directory
- before linking, and set the variables NEW_FILES, NEW_LIBS,
- NEW_MODULES and TO_LOAD
- and any other files needed by link.sh .
- Note that in link.sh the module set directory is referred to as "$modulename"/.
- The NEW_FILES variable shall contain a space-separated list of files that
- belong to the module set and will belong to every new linking set. The NEW_LIBS
- variable shall contain a space-separated list of files or C compiler switches
- that need to be passed to the C compiler when linking the lisp.run belonging
- to a new linking set. The NEW_MODULES variable shall contain a space-separated
- list of the module names belonging to the module set. Normally, every .c file
- in the module set defines a module of its own. The module name is derived from
- the file name. The TO_LOAD variable shall contain a space-separated list of
- Lisp files to load before building the lispinit.mem belonging to a new linking
- set.
-
- The command
- "clisp-link create-module-set <module-dir> <file1.c> ..."
- creates a module set in <module-dir> which refers (via symbolic links) to
- file1.c etc. The files are expected to be modules of their own.
-
- The command
- "clisp-link add-module-set <module-dir> <source-dir> <destination-dir>"
- combines a linking set in <source-dir> and a module in <module-dir> to a new
- linking set, in a directory <destination-dir> which is newly created.
-
- Example
- -------
-
- To link in the FFI bindings for the Linux operating system, the following
- steps are needed. (Step 1 and step 2 need not be executed in this order.)
-
- 1. Create a new module set:
-
- $ clisp-link create-module-set linux /somewhere/bindings/linux.c
-
- Modify the newly created linux/link.sh to add "-lm" to the libraries:
-
- NEW_LIBS="$file_list"
- -->
- NEW_LIBS="$file_list -lm"
-
- Modify the newly created linux/link.sh to load linux.fas before saving
- the memory image:
-
- TO_LOAD=''
- -->
- TO_LOAD='/somewhere/bindings/linux.fas'
-
- 2. Compile linux.lsp, creating linux.c:
-
- $ clisp -c /somewhere/bindings/linux.lsp
-
- 3. Create a new linking set:
-
- $ clisp-link add-module-set linux base base+linux
-
- 4. Run and try it:
-
- $ base+linux/lisp.run -M base+linux/lispinit.mem
- > (linux::stat "/tmp")
-
- 99.4. The Foreign Function Call Facility
- ----------------------------------------
-
- The Foreign Function Call Facility
- ==================================
-
- A foreign function description is written as a Lisp file,
- and when compiled it produces a .c file which is then compiled
- by the C compiler and may be linked together with lisp.a.
-
- All symbols relating to the foreign function interface are exported from
- the package FFI. To use them, (USE-PACKAGE "FFI").
-
- Special FFI forms may appear anywhere in the Lisp file.
-
- Overview
- --------
-
- These are the special FFI forms. We have taken a pragmatic approach:
- the only foreign languages we support for now are C and ANSI C.
-
- (DEF-C-TYPE name <c-type>)
-
- (DEF-C-VAR name {option}*)
- option ::=
- (:name <c-name>)
- | (:type <c-type>)
- | (:read-only <boolean>)
- | (:alloc <allocation>)
-
- (DEF-CALL-OUT name {option}*)
- option ::=
- (:name <c-name>)
- | (:arguments {(arg-name <c-type> [<param-mode> [<allocation>]])}*)
- | (:return-type <c-type> [<allocation>])
- | (:language <language>)
-
- (DEF-CALL-IN name {option}*)
- option ::=
- (:name <c-name>)
- | (:arguments {(arg-name <c-type> [<param-mode> [<allocation>]])}*)
- | (:return-type <c-type> [<allocation>])
- | (:language <language>)
-
- (DEF-C-CALL-OUT name {option}*)
- option ::=
- (:name <c-name>)
- | (:arguments {(arg-name <c-type> [<param-mode> [<allocation>]])}*)
- | (:return-type <c-type> [<allocation>])
-
- (DEF-C-CALL-IN name {option}*)
- option ::=
- (:name <c-name>)
- | (:arguments {(arg-name <c-type> [<param-mode> [<allocation>]])}*)
- | (:return-type <c-type> [<allocation>])
-
- (DEF-C-STRUCT name (<ident> <c-type>)*)
-
- (DEF-C-ENUM name {<ident> | (<ident> [<value>])}*)
-
- (C-LINES format-string {argument}*)
-
- (ELEMENT c-place {index}*)
- (DEREF c-place)
- (SLOT c-place slot-name)
- (CAST c-place <c-type>)
-
- (TYPEOF c-place)
- (SIZEOF c-place), (SIZEOF <c-type>)
- (BITSIZEOF c-place), (BITSIZEOF <c-type>)
-
- (VALIDP foreign-entity)
-
- name is any Lisp symbol.
-
- <c-name> is a string.
-
- (Foreign) C types
- -----------------
-
- Foreign C types are used in the FFI. They are *not* regular Common Lisp
- types or CLOS classes.
-
- A <c-type> is either a predefined C type or the name of a type defined by
- DEF-C-TYPE.
-
- The simple C types are these:
-
- Lisp name Lisp equiv C equiv ILU equiv
- nil NIL void (o)
- boolean (MEMBER NIL T) int BOOLEAN
- character STRING-CHAR char SHORT CHARACTER
- char INTEGER signed char
- uchar INTEGER unsigned char
- short INTEGER short
- ushort INTEGER unsigned short
- int INTEGER int
- uint INTEGER unsigned int
- long INTEGER long
- ulong INTEGER unsigned long
- uint8 (UNSIGNED-BYTE 8) uint8 BYTE
- sint8 (SIGNED-BYTE 8) sint8
- uint16 (UNSIGNED-BYTE 16) uint16 SHORT CARDINAL
- sint16 (SIGNED-BYTE 16) sint16 SHORT INTEGER
- uint32 (UNSIGNED-BYTE 32) uint32 CARDINAL
- sint32 (SIGNED-BYTE 32) sint32 INTEGER
- uint64 (UNSIGNED-BYTE 64) uint64 LONG CARDINAL (*)
- sint64 (SIGNED-BYTE 64) sint64 LONG INTEGER (*)
- single-float SINGLE-FLOAT float
- double-float DOUBLE-FLOAT double
- (o) as a result type only.
- (*) does not work on all platforms.
-
- The predefined C types are:
-
- c-type ::=
- <simple-c-type>
- | C-POINTER
- | C-STRING
- | (C-STRUCT <class> (<ident> <c-type>)*)
- | (C-UNION (<ident> <c-type>)*)
- | (C-ARRAY <c-type> dimensions)
- dimensions ::= number | ({number}*)
- | (C-ARRAY-MAX <c-type> maxdimension)
- maxdimension ::= number
- | (C-FUNCTION {option}*)
- option ::=
- (:arguments {(arg-name <c-type> [<param-mode> [<allocation>]])}*)
- | (:return-type <c-type> [<allocation>])
- | (:language <language>)
- | (C-PTR <c-type>)
- | (C-PTR-NULL <c-type>)
- | (C-ARRAY-PTR <c-type>)
-
- (DEF-C-TYPE name <c-type>)
- makes name a shortcut for <c-type>. Note that <c-type> may already refer
- to name. Forward declarations of types are not possible, however.
-
- The type C-POINTER corresponds to what C calls "void*", an opaque pointer.
-
- The type C-STRING corresponds to what C calls "char*", a zero-terminated
- string. Its Lisp equivalent is a string, without the trailing zero character.
-
- The type (C-STRUCT class (ident1 type1) ... (ident2 type2)) is equivalent to
- what C calls "struct { type1 ident1; ...; type2 ident2; }". Its Lisp
- equivalent is: if class is VECTOR, a simple-vector; if class is LIST, a list;
- if class is a symbol naming a structure or CLOS class: an instance of this
- class, with slots of names ident1,...,ident2.
-
- The type (C-UNION (ident1 type1) ... (ident2 type2)) is equivalent to what C
- calls "union { type1 ident1; ...; type2 ident2; }". Conversion to and from
- Lisp assumes that a value is to be viewed as being of type1.
-
- The type (C-ARRAY type dim1 ... dim2) is equivalent to what C calls
- "type [dim1]...[dim2]". Note that when an array is passed as an argument to
- a function in C, it is actually passed as a pointer; you therefore have to
- write (C-PTR (C-ARRAY ...)) for this argument's type.
-
- The type (C-ARRAY-MAX type maxdim) is equivalent to what C calls
- "type [maxdim]", an array containing up to maxdim elements. The array is
- zero-terminated if it contains less than maxdim elements. Conversion from Lisp
- of an array with more than maxdim elements silently ignores the superfluous
- elements.
-
- The type (C-PTR type) is equivalent to what C calls "type *": a pointer to
- a single item of the given type.
-
- The type (C-PTR-NULL type) is also equivalent to what C calls "type *": a
- pointer to a single item of the given type, with the exception that C NULL
- corresponds to Lisp NIL.
-
- The type (C-ARRAY-PTR type) is equivalent to what C calls "type (*)[]":
- a pointer to a zero-terminated array of items of the given type.
-
- The type (C-FUNCTION (:return-type rtype) (:arguments (arg1 type1 ...) ...))
- designates a C function that can be called according to the given prototype
- (rtype (*) (type1, ...)).
- The <language> is either :C (denotes K&R C) or :STDC (denotes ANSI C). It
- specifies whether the C function has been compiled by a K&R C compiler or by
- an ANSI C compiler.
- Conversion between C functions and Lisp functions is transparent.
-
- (DEF-C-STRUCT <name> (<ident> <c-type>)*) defines <name> to be both a
- DEFSTRUCT structure type and a foreign C type with the given slots.
-
- (DEF-C-ENUM <name> {<ident> | (<ident> [<value>])}*) defines <ident>s as
- constants, similarly to the C declaration enum { <ident> [= <value>], ... };
-
- (C-LINES format-string {argument}*)
- outputs the string (FORMAT nil format-string {argument}*) to the C output
- file. This is a rarely needed low-level facility.
-
- The form (SIZEOF <c-type>) returns the size and alignment of a C type,
- measured in bytes.
-
- The form (BITSIZEOF <c-type>) returns the size and alignment of a C type,
- measured in bits.
-
- The predicate (VALIDP foreign-entity) returns NIL if the foreign-entity
- (e.g. the Lisp equivalent of a C-POINTER) refers to a pointer which is
- invalid because it comes from a previous Lisp session. It returns T if
- foreign-entity can be used within the current Lisp process.
-
- Foreign variables
- -----------------
-
- Foreign variables are variables whose storage is allocated in the foreign
- language module. They can nevertheless be evaluated and modified through SETQ,
- just as normal variables can, except that the range of allowed values is
- limited according to the variable's foreign type. Note that for a foreign
- variable X the form (EQL X X) is not necessarily true, since every time X is
- evaluated its foreign value is converted to a freshly created Lisp value.
-
- (DEF-C-VAR name {option}*)
- option ::=
- (:name <c-name>)
- | (:type <c-type>)
- | (:read-only <boolean>)
- | (:alloc <allocation>)
-
- defines a foreign variable. `name' is the Lisp name, a regular Lisp symbol.
-
- The :name option specifies the name, as seen from C, as a string. If not
- specified, it is derived from the print name of the Lisp name.
-
- The :type option specifies the variable's foreign type.
-
- If the :read-only option is specified and non-NIL, it will be impossible
- to change the variable's value from within Lisp (using SETQ or similar).
-
- The :alloc option can be either :NONE or :MALLOC-FREE and defaults to :NONE.
- If it is :MALLOC-FREE, any values of type C-STRING, (C-PTR ...),
- (C-PTR-NULL ...), (C-ARRAY-PTR ...) within the foreign value are assumed to
- be pointers to malloc()-allocated storage, and when SETQ replaces an old
- value by a new one, the old storage is freed using free() and the new storage
- allocated using malloc(). If it is :NONE, SETQ assumes that the pointers
- point to good storage (not NULL!) and overwrites the old values by the new
- ones. This is dangerous (just think of overwriting a string with a longer one
- or storing some data in a NULL pointer...) and deprecated.
-
- Operations on foreign places
- ----------------------------
-
- A foreign variable `name' defined by DEF-C-VAR defines a "place", i.e.
- a form which can also be used as argument to SETF. (An "lvalue" in C
- terminology.) The following operations are available on foreign places:
-
- (ELEMENT place index1 ... indexn)
- Array element: If place is of foreign type (C-ARRAY <c-type> dim1 ... dimn)
- and 0 <= index1 < dim1, ..., 0 <= indexn < dimn, this will be the place
- corresponding to (aref place index1 ... indexn) or place[index1]...[indexn].
- It is a place of type <c-type>.
- If place is of foreign type (C-ARRAY-MAX <c-type> dim) and 0 <= index < dim,
- this will be the place corresponding to (aref place index) or place[index].
- It is a place of type <c-type>.
-
- (DEREF place)
- Dereference pointer: If place is of foreign type (C-PTR <c-type>) or
- (C-PTR-NULL <c-type>), this will be the place the pointer points to. It is a
- place of type <c-type>. For (C-PTR-NULL <c-type>), the place may not be NULL.
-
- (SLOT place slot-name)
- Struct or union component: If place is of foreign type
- (C-STRUCT <class> ... (slot-name <c-type>) ...) or of type
- (C-UNION ... (slot-name <c-type>) ...), this will be of type <c-type>.
-
- (CAST place <c-type>)
- Type change: A place denoting the same memory locations as the original place,
- but of type <c-type>.
-
- (TYPEOF place)
- returns the <c-type> corresponding to the place.
-
- (SIZEOF place) returns the size and alignment of the C type of place,
- measured in bytes.
-
- (BITSIZEOF place) returns the size and alignment of the C type of place,
- measured in bits.
-
- Foreign functions
- -----------------
-
- Foreign functions are functions which are defined in the foreign language.
- There are named foreign functions (imported via DEF-CALL-OUT or created via
- DEF-CALL-IN) and anonymous foreign functions; they arise through conversion
- of function pointers.
-
- A "call-out" function is a foreign function called from Lisp: control flow
- temporarily leaves Lisp.
- A "call-in" function is a Lisp function called from the foreign language:
- control flow temporary enters Lisp.
-
- (DEF-CALL-OUT name {option}*)
- option ::=
- (:name <c-name>)
- | (:arguments {(arg-name <c-type> [<param-mode> [<allocation>]])}*)
- | (:return-type <c-type> [<allocation>])
- | (:language <language>)
-
- defines a named call-out function. Any Lisp function call to #'name is
- redirected to call the C function <c-name>.
-
- DEF-C-CALL-OUT is equivalent to DEF-CALL-OUT with :LANGUAGE :C.
-
- (DEF-CALL-IN name {option}*)
- option ::=
- (:name <c-name>)
- | (:arguments {(arg-name <c-type> [<param-mode> [<allocation>]])}*)
- | (:return-type <c-type> [<allocation>])
- | (:language <language>)
-
- defines a named call-in function. Any C function call to the C function
- <c-name> is redirected to call the Lisp function #'name.
-
- DEF-C-CALL-IN is equivalent to DEF-CALL-IN with :LANGUAGE :C.
-
- Argument and result passing conventions
- ---------------------------------------
-
- When passed to and from functions, allocation of arguments and results is
- handled as follows:
-
- Values of <simple-c-type>, C-POINTER are passed on the stack, with dynamic
- extent. The <allocation> is effectively ignored.
-
- Values of type C-STRING, (C-PTR ...), (C-PTR-NULL ...), (C-ARRAY-PTR ...) need
- storage. The <allocation> specifies the allocation policy:
- <allocation> is :NONE means that no storage is allocated.
- <allocation> is :ALLOCA means allocation of storage on the stack,
- which has dynamic extent.
- <allocation> is :MALLOC-FREE means that storage will be allocated
- via malloc() and freed via free().
- If no <allocation> is specified, the default <allocation> is :NONE for most
- types, but :ALLOCA for C-STRING and (C-PTR ...) and (C-PTR-NULL ...) and
- (C-ARRAY-PTR ...) and for :OUT arguments. [Subject to change!]
- The :MALLOC-FREE policy provides the ability to pass arbitrarily nested
- structs containing pointers pointing to structs ... within a single conversion.
-
- For call-out functions:
- For arguments passed from Lisp to C:
- If <allocation> is :MALLOC-FREE,
- Lisp allocates the storage using malloc() and never deallocates it.
- The C function is supposed to call free() when done with it.
- If <allocation> is :ALLOCA,
- Lisp allocates the storage on the stack, with dynamic extent. It is
- freed when the C function returns.
- If <allocation> is :NONE,
- Lisp assumes that the pointer already points to a valid area of the
- proper size and puts the result value there. This is dangerous! and
- deprecated.
- For results passed from C to Lisp:
- If <allocation> is :MALLOC-FREE,
- Lisp calls free() on it when done.
- If <allocation> is :NONE,
- Lisp does nothing.
- For call-in functions:
- For arguments passed from C to Lisp:
- If <allocation> is :MALLOC-FREE,
- Lisp calls free() on it when done.
- If <allocation> is :ALLOCA or :NONE,
- Lisp does nothing.
- For results passed from Lisp to C:
- If <allocation> is :MALLOC-FREE,
- Lisp allocates the storage using malloc() and never deallocates it.
- The C function is supposed to call free() when done with it.
- If <allocation> is :NONE,
- Lisp assumes that the pointer already points to a valid area of the
- proper size and puts the result value there. This is dangerous! and
- deprecated.
-
- A function parameter's <param-mode> may be
- either :IN (means: read-only):
- The caller passes information to the callee.
- or :OUT (means: write-only):
- The callee passes information back to the caller on return.
- When viewed as a Lisp function, there is no Lisp argument corresponding
- to this, instead it means an additional return value.
- or :IN-OUT (means: read-write):
- Information is passed from the caller to the callee and then back to
- the caller. When viewed as a Lisp function, the ":OUT" value is
- returned as an additional multiple value.
- The default is :IN.
-
- [Currently, only :IN is fully implemented. :OUT works only with
- <allocation> = :ALLOCA.]
-
- On AmigaOS, <allocation> may not be :MALLOC-FREE because there is no commonly
- used malloc()/free() library function.
-
- On AmigaOS, the <allocation> may be followed by a register specification,
- any of the symbols :D0, :D1, :D2, :D3, :D4, :D5, :D6, :D7, :A0, :A1, :A2,
- :A3, :A4, :A5, :A6, each representing one 680x0 register. This works only
- for integral types: integers, pointers, C-STRING, C-FUNCTION.
-
- Passing C-STRUCT, C-UNION, C-ARRAY, C-ARRAY-MAX values as arguments (not via
- pointers) is only possible to the extent the C compiler supports it. Most C
- compilers do it right, but some C compilers (such as gcc on hppa) have
- problems with this.
-
- Examples
- --------
-
- Ex. 1: The C declaration
-
- struct foo {
- int a;
- struct foo * b[100];
- };
-
- corresponds to
-
- (def-c-struct foo
- (a int)
- (b (c-array (c-ptr foo) 100))
- )
-
- The element access
-
- struct foo f;
- f.b[7].a
-
- corresponds to
-
- (declare (type foo f))
- (foo-a (aref (foo-b f) 7)) or (slot-value (aref (slot-value f 'b) 7) 'a)
-
- Ex. 2: Here is an example of an external C variable and some accesses:
-
- struct bar {
- short x, y;
- char a, b;
- int z;
- struct bar * n;
- };
-
- extern struct bar * my_struct;
-
- my_struct->x++;
- my_struct->a = 5;
- my_struct = my_struct->n;
-
- corresponds to
-
- (def-c-struct bar
- (x short)
- (y short)
- (a char)
- (b char) ; or (b character) if it represents a character, not a number
- (z int)
- (n (c-ptr bar))
- )
-
- (def-c-var my_struct (:type (c-ptr bar)))
-
- (setq my_struct (let ((s my_struct)) (incf (slot-value s 'x)) s))
- or (incf (slot my_struct 'x))
- (setq my_struct (let ((s my_struct)) (setf (slot-value s 'a) 5) s))
- or (setf (slot my_struct 'a) 5)
- (setq my_struct (slot-value my_struct 'n))
- or (setq my_struct (deref (slot my_struct 'n)))
-
- Ex. 3: An example for calling an external function:
- On ANSI C systems, <stdlib.h> contains the declarations
-
- typedef struct {
- int quot; /* Quotient */
- int rem; /* Remainder */
- } div_t;
- extern div_t div (int numer, int denom);
-
- This translates to
-
- (def-c-struct div_t
- (quot int)
- (rem int)
- )
- (def-c-call-out div (:arguments (numer int) (denom int))
- (:return-type div_t)
- )
-
- Sample call from within Lisp:
-
- > (div 20 3)
- #S(DIV :QUOT 6 :REM 2)
-
- Ex. 4: Another example for calling an external function:
-
- Suppose the following is defined in a file "cfun.c":
-
- struct cfunr { int x; char *s; };
- struct cfunr * cfun (i,s,r,a)
- int i;
- char *s;
- struct cfunr * r;
- int a[10];
- {
- int j;
- struct cfunr * r2;
- printf("i = %d\n", i);
- printf("s = %s\n", s);
- printf("r->x = %d\n", r->x);
- printf("r->s = %s\n", r->s);
- for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
- r2 = (struct cfunr *) malloc (sizeof (struct cfunr));
- r2->x = i+5;
- r2->s = "A C string";
- return r2;
- }
-
- It is possible to call this function from Lisp using the file "callcfun.lsp"
- (don't call it "cfun.lsp" - COMPILE-FILE would overwrite "cfun.c") whose
- contents is:
-
- (in-package "TEST-C-CALL" :use '("LISP" "FFI"))
- (def-c-struct cfunr (x int) (s c-string))
- (def-c-call-out cfun (:arguments (i int)
- (s c-string)
- (r (c-ptr cfunr) :in :alloca)
- (a (c-ptr (c-array int 10)) :in :alloca)
- )
- (:return-type (c-ptr cfunr))
- )
- (defun call-cfun ()
- (cfun 5 "A Lisp string" (make-cfunr :x 10 :s "Another Lisp string")
- '#(0 1 2 3 4 5 6 7 8 9)
- ) )
-
- Use the module facility:
-
- $ clisp-link create-module-set cfun callcfun.c
- $ cc -O -c cfun.c
- $ cd cfun
- $ ln -s ../cfun.o cfun.o
- Add cfun.o to NEW_LIBS and NEW_FILES in link.sh.
- $ cd ..
- $ base/lisp.run -M base/lispinit.mem -c callcfun.lsp
- $ clisp-link add-module-set cfun base base+cfun
- $ base+cfun/lisp.run -M base+cfun/lispinit.mem -i callcfun
- > (test-c-call::call-cfun)
- i = 5
- s = A Lisp string
- r->x = 10
- r->s = Another Lisp string
- a[0] = 0.
- a[1] = 1.
- a[2] = 2.
- a[3] = 3.
- a[4] = 4.
- a[5] = 5.
- a[6] = 6.
- a[7] = 7.
- a[8] = 8.
- a[9] = 9.
- #S(TEST-C-CALL::CFUNR :X 10 :S "A C string")
- >
- $ rm -r base+cfun
-
- Note that there is a memory leak here: The return value r2 of cfun() is
- malloc()ed but never free()d. Specifying
- (:return-type (c-ptr cfunr) :malloc-free)
- is not an alternative because this would also free(r2->x) but r2->x is a
- pointer to static data.
-
- Ex. 5: To sort an array of double-floats using the Lisp function SORT
- instead of the C library function qsort(), one can use the following
- interface code "sort1.c". The main problem is to pass a variable-sized array.
-
- extern void lispsort_begin (int);
- void* lispsort_function;
- void lispsort_double (int n, double * array)
- {
- double * sorted_array;
- int i;
- lispsort_begin(n); /* store #'sort2 in lispsort_function */
- sorted_array = ((double * (*) (double *)) lispsort_function) (array);
- for (i = 0; i < n; i++) array[i] = sorted_array[i];
- free(sorted_array);
- }
-
- This is accompanied by "sort2.lsp":
-
- (use-package "FFI")
- (def-call-in lispsort_begin (:arguments (n int))
- (:return-type nil)
- (:language :stdc)
- )
- (def-c-var lispsort_function (:type c-pointer))
- (defun lispsort_begin (n)
- (setf (cast lispsort_function
- `(c-function
- (:arguments (v (c-ptr (c-array double-float ,n))))
- (:return-type (c-ptr (c-array double-float ,n))
- :malloc-free
- ) )
- )
- #'sort2
- ) )
- (defun sort2 (v)
- (declare (type vector v))
- (sort v #'<)
- )
-
- To test this, use the following test file "sorttest.lsp":
-
- (def-call-out sort10
- (:name "lispsort_double")
- (:language :stdc)
- (:arguments (n int)
- (array (c-ptr (c-array double-float 10))
- :in-out
- ) ) )
-
- Now try
-
- $ clisp-link create-module-set sort sort2.c sorttest.c
- $ cc -O -c sort1.c
- $ cd sort
- $ ln -s ../sort1.o sort1.o
- Add sort1.o to NEW_LIBS and NEW_FILES in link.sh.
- $ cd ..
- $ base/lisp.run -M base/lispinit.mem -c sort2.lsp sorttest.lsp
- $ clisp-link add-module-set sort base base+sort
- $ base+sort/lisp.run -M base+sort/lispinit.mem -i sort2 sorttest
- > (sort10 10 '#(0.501d0 0.528d0 0.615d0 0.550d0 0.711d0
- 0.523d0 0.585d0 0.670d0 0.271d0 0.063d0))
- #(0.063d0 0.271d0 0.501d0 0.523d0 0.528d0 0.55d0 0.585d0 0.615d0 0.67d0 0.711d0)
- $ rm -r base+sort
-
- 99.6. Graphics
- --------------
-
- Graphics primitives in CLISP
- ============================
-
- In CLISP 1994-01-07 or newer,
- * DOS version,
- * Linux version, installed setuid root,
- there are some pixel graphics primitives in the SYSTEM package.
- They operate on a VGA card.
-
- Similar pixel graphics primitives can be used in the
- * Unix version running under X11
- by use of the small XTERM package available on
- ma2s2.mathematik.uni-karlsruhe.de.
-
- This is the description of the PC/VGA graphics primitives:
-
- (SYSTEM::GRAPH-INIT [width [height [colors]]])
- initializes the graphics system. The width, height parameters are hints for
- the size of the desired graphics screen (positive integers). The colors
- parameter is a hint for the number of colors. The actual width, height
- is implementation dependent, currently up to 640x480 on VGA cards and up to
- 1024x768 on ET4000 SVGA cards.
- Returns an alist ((color-value color-keyword) ...) which lists the available
- colours and their numerical equivalents.
-
- (SYSTEM::GRAPH-SHOW)
- switches the graphics hardware so that the graphics screen is visible. The
- text screen is activated on any text output.
-
- (SYSTEM::GRAPH-CLEAR [color])
- fills the entire graphics screen with a single color.
-
- (SYSTEM::GRAPH-DIMS)
- returns two values: the actual width and the actual height of the graphics
- screen (in pixels).
-
- If (SYSTEM::GRAPH-DIMS) returns the values w and h, then valid screen
- coordinates are pairs (x,y) with 0 <= x < w and 0 <= y < h. x=0 denotes the
- left edge, y=0 the top edge.
-
- (SYSTEM::GRAPH-DOT x y)
- returns the colour of the pixel (x,y).
- (SYSTEM::GRAPH-DOT x y color)
- sets the colour of the pixel (x,y) to color.
-
- (SYSTEM::GRAPH-BOX x1 y1 x2 y2 color)
- draws a box (= filled rectangle) in colour color, the vertices being the pixels
- (x1,y1) (x2,y1)
- (x1,y2) (x2,y2)
-
- (SYSTEM::GRAPH-LINE x1 y1 x2 y2 color)
- Draws a line in colour color from pixel (x1,y1) to pixel (x2,y2).
-
- (SYSTEM::GRAPH-TEXT x y dir string color)
- Paints the text contained in string, starting at (x,y), in colour color,
- and returns as values the end coordinates (x,y). dir is the direction:
- 0 goes to the right, 90 vertically up, 180 to the left, 270 vertically down.
-
- This specification is subject to change.
-
- 99.7 Socket Streams
- -------------------
-
- (SOCKET-SERVER [port])
-
- This function creates a socket, and binds a port the socket, and then
- listens for connect attempts. The server exists to watch for client
- connect attempts.
-
- (SOCKET-SERVER-CLOSE socket-server)
-
- Closes down the server socket.
-
- (SOCKET-SERVER-PORT socket-server)
-
- Returns the port which was bound using SOCKET-SERVER.
-
- (SOCKET-WAIT socket-server [seconds [microseconds]])
-
- Given time argument(s), waits for (possibly zero) fixed duration for a connect
- on the socket-server. Without an argument, SOCKET-WAIT blocks indefinitely.
-
- (SOCKET-ACCEPT socket-server)
-
- Creates the server-side two-way stream for the connection.
-
- (SOCKET-CONNECT port [host])
-
- Attempts to create a client-side two-way stream. Blocks until
- the server accepts the connections.
-
- (SOCKET-STREAM-HOST socket-stream)
- (SOCKET-STREAM-PORT socket-stream)
-
- These two functions return information about the
- socket stream. For a server, SOCKET-STREAM-HOST
- returns NIL.
-
- (SOCKET-SERVICE-PORT "service-name")
-
- A convenience function for looking up a port given the service name.
-
- (SOCKET-STREAM-PEER-HOST socket-stream)
-
- Given a stream, this function returns the name
- of the host on the opposite side of the connection;
- the server-side can use this to see who connected.
-
-
- Authors:
- --------
-
- Bruno Haible Michael Stoll
- Augartenstra▀e 40 Gallierweg 39
- D - 76137 Karlsruhe D - 53117 Bonn
- Germany Germany
-
- Maintainer: marcus@sysc.pdx.edu
- haible@ma2s2.mathematik.uni-karlsruhe.de
-